mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-13 04:53:06 +00:00
45621: finished filter facets for search sidebar
This commit is contained in:
@@ -94,9 +94,9 @@
|
|||||||
"filters": {
|
"filters": {
|
||||||
"head": "Filters",
|
"head": "Filters",
|
||||||
"reset": "Reset filters",
|
"reset": "Reset filters",
|
||||||
"facet-filter": {
|
"filter": {
|
||||||
"show-more": "Show more",
|
"show-more": "Show more",
|
||||||
"show-less": "Show less",
|
"show-less": "Collapse",
|
||||||
"author": {
|
"author": {
|
||||||
"placeholder": "Author name",
|
"placeholder": "Author name",
|
||||||
"head": "Author"
|
"head": "Author"
|
||||||
@@ -108,6 +108,10 @@
|
|||||||
"subject": {
|
"subject": {
|
||||||
"placeholder": "Subject",
|
"placeholder": "Subject",
|
||||||
"head": "Subject"
|
"head": "Subject"
|
||||||
|
},
|
||||||
|
"date": {
|
||||||
|
"placeholder": "Date",
|
||||||
|
"head": "Date"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,32 @@
|
|||||||
<a *ngFor="let value of filterValues; let i=index" class="d-block" [routerLink]="[getSearchLink()]"
|
<div>
|
||||||
[queryParams]="getQueryParams(value) | async">
|
<div class="filters">
|
||||||
|
<a *ngFor="let value of selectedValues" class="d-block"
|
||||||
|
[routerLink]="[getSearchLink()]"
|
||||||
|
[queryParams]="getQueryParamsWithout(value) | async">
|
||||||
|
<input type="checkbox" [checked]="true"/>
|
||||||
|
<span class="filter-value">{{value}}</span>
|
||||||
|
</a>
|
||||||
|
<a *ngFor="let value of filterValues; let i=index" class="d-block"
|
||||||
|
[routerLink]="[getSearchLink()]"
|
||||||
|
[queryParams]="getQueryParamsWith(value.value) | async">
|
||||||
<ng-template [ngIf]="i < (facetCount | async)">
|
<ng-template [ngIf]="i < (facetCount | async)">
|
||||||
<input type="checkbox" [checked]="isChecked(value) | async"/>
|
<input type="checkbox" [checked]="false"/>
|
||||||
<span class="filter-value">{{value.value}}</span>
|
<span class="filter-value">{{value.value}}</span>
|
||||||
<span class="filter-value-count float-right">({{value.count}})</span>
|
<span class="filter-value-count float-right">({{value.count}})</span>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</a>
|
</a>
|
||||||
<a *ngIf="filterValues.length > (facetCount | async)" (click)="showMore()">{{"search.filters.facet-filter.show-more"
|
<div class="clearfix toggle-more-filters">
|
||||||
|
<a class="float-left" *ngIf="filterValues.length > (facetCount | async)"
|
||||||
|
(click)="showMore()">{{"search.filters.filter.show-more"
|
||||||
| translate}}</a>
|
| translate}}</a>
|
||||||
<a *ngIf="(currentPage | async) > 1" (click)="showLess()">{{"search.filters.facet-filter.show-less" |
|
<a class="float-right" *ngIf="(currentPage | async) > 1" (click)="showLess()">{{"search.filters.filter.show-less"
|
||||||
translate}}</a>
|
| translate}}</a>
|
||||||
|
</div>
|
||||||
<input type="text"
|
</div>
|
||||||
[placeholder]="'search.filters.facet-filter.' + filterConfig.name + '.placeholder'| translate"/>
|
<form #form="ngForm" (ngSubmit)="onSubmit(form.value)" class="add-filter">
|
||||||
|
<input type="text" [(ngModel)]="filter" name="filter" class="form-control"
|
||||||
|
aria-label="New filter input"
|
||||||
|
[placeholder]="'search.filters.filter.' + filterConfig.name + '.placeholder'| translate"/>
|
||||||
|
<input type="submit" class="d-none"/>
|
||||||
|
</form>
|
||||||
|
</div>
|
@@ -1,2 +1,18 @@
|
|||||||
@import '../../../../../styles/variables.scss';
|
@import '../../../../../styles/variables.scss';
|
||||||
@import '../../../../../styles/mixins.scss';
|
@import '../../../../../styles/mixins.scss';
|
||||||
|
|
||||||
|
.filters {
|
||||||
|
margin-top: $spacer/2;
|
||||||
|
margin-bottom: $spacer/2;
|
||||||
|
a {
|
||||||
|
color: $body-color;
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.toggle-more-filters a {
|
||||||
|
color: $link-color;
|
||||||
|
text-decoration: underline;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,10 +1,10 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { FacetValue } from '../../../search-service/facet-value.model';
|
import { FacetValue } from '../../../search-service/facet-value.model';
|
||||||
import { SearchFilterConfig } from '../../../search-service/search-filter-config.model';
|
import { SearchFilterConfig } from '../../../search-service/search-filter-config.model';
|
||||||
import { SearchService } from '../../../search-service/search.service';
|
import { Params, Router } from '@angular/router';
|
||||||
import { Params } from '@angular/router';
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { SearchFilterService } from '../search-filter.service';
|
import { SearchFilterService } from '../search-filter.service';
|
||||||
|
import { isNotEmpty } from '../../../../shared/empty.util';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component renders a simple item page.
|
* This component renders a simple item page.
|
||||||
@@ -21,9 +21,11 @@ import { SearchFilterService } from '../search-filter.service';
|
|||||||
export class SidebarFacetFilterComponent implements OnInit {
|
export class SidebarFacetFilterComponent implements OnInit {
|
||||||
@Input() filterValues: FacetValue[];
|
@Input() filterValues: FacetValue[];
|
||||||
@Input() filterConfig: SearchFilterConfig;
|
@Input() filterConfig: SearchFilterConfig;
|
||||||
|
@Input() selectedValues: string[];
|
||||||
currentPage: Observable<number>;
|
currentPage: Observable<number>;
|
||||||
|
filter: string;
|
||||||
|
|
||||||
constructor(private filterService: SearchFilterService) {
|
constructor(private filterService: SearchFilterService, private router: Router) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@@ -38,8 +40,12 @@ export class SidebarFacetFilterComponent implements OnInit {
|
|||||||
return this.filterService.searchLink;
|
return this.filterService.searchLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
getQueryParams(value: FacetValue): Observable<Params> {
|
getQueryParamsWith(value: string): Observable<Params> {
|
||||||
return this.filterService.getFilterValueURL(this.filterConfig, value.value);
|
return this.filterService.getQueryParamsWith(this.filterConfig, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
getQueryParamsWithout(value: string): Observable<Params> {
|
||||||
|
return this.filterService.getQueryParamsWithout(this.filterConfig, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
get facetCount(): Observable<number> {
|
get facetCount(): Observable<number> {
|
||||||
@@ -60,6 +66,16 @@ export class SidebarFacetFilterComponent implements OnInit {
|
|||||||
|
|
||||||
getCurrentPage(): Observable<number> {
|
getCurrentPage(): Observable<number> {
|
||||||
return this.filterService.getPage(this.filterConfig.name);
|
return this.filterService.getPage(this.filterConfig.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit(data: any) {
|
||||||
|
if (isNotEmpty(data.filter)) {
|
||||||
|
this.getQueryParamsWith(data.filter).first().subscribe((a) => {
|
||||||
|
this.router.navigate([this.getSearchLink()], { queryParams: a }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this.filter = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<div>
|
<div>
|
||||||
<div (click)="toggle()" class="filter-name">{{filter.name}} <span class="fa float-right"
|
<div (click)="toggle()" class="filter-name"><h5 class="d-inline-block mb-0">{{'search.filters.filter.' + filter.name + '.head'| translate}}</h5> <span class="filter-toggle fa float-right"
|
||||||
[ngClass]="(isCollapsed() | async) ? 'fa-plus' : 'fa-minus'"></span></div>
|
[ngClass]="(isCollapsed() | async) ? 'fa-plus' : 'fa-minus'"></span></div>
|
||||||
<div [@slide]="(isCollapsed() | async) ? 'collapsed' : 'expanded'" class="search-filter-wrapper">
|
<div [@slide]="(isCollapsed() | async) ? 'collapsed' : 'expanded'" class="search-filter-wrapper">
|
||||||
<ds-search-facet-filter [filterConfig]="filter"
|
<ds-search-facet-filter [filterConfig]="filter"
|
||||||
[filterValues]="(filterValues | async)?.payload"></ds-search-facet-filter>
|
[filterValues]="(filterValues | async)?.payload" [selectedValues]="getSelectedValues() | async"></ds-search-facet-filter>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@@ -1,6 +1,12 @@
|
|||||||
@import '../../../../styles/variables.scss';
|
@import '../../../../styles/variables.scss';
|
||||||
@import '../../../../styles/mixins.scss';
|
@import '../../../../styles/mixins.scss';
|
||||||
|
|
||||||
.search-filter-wrapper {
|
:host {
|
||||||
|
border: 1px solid map-get($theme-colors, light);
|
||||||
|
.search-filter-wrapper {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.filter-toggle {
|
||||||
|
line-height: $line-height-base;
|
||||||
|
}
|
||||||
}
|
}
|
@@ -6,6 +6,7 @@ import { FacetValue } from '../../search-service/facet-value.model';
|
|||||||
import { SearchFilterService } from './search-filter.service';
|
import { SearchFilterService } from './search-filter.service';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { slide } from '../../../shared/animations/slide';
|
import { slide } from '../../../shared/animations/slide';
|
||||||
|
import { RouteService } from '../../../shared/route.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component renders a simple item page.
|
* This component renders a simple item page.
|
||||||
@@ -17,7 +18,7 @@ import { slide } from '../../../shared/animations/slide';
|
|||||||
selector: 'ds-search-filter',
|
selector: 'ds-search-filter',
|
||||||
styleUrls: ['./search-filter.component.scss'],
|
styleUrls: ['./search-filter.component.scss'],
|
||||||
templateUrl: './search-filter.component.html',
|
templateUrl: './search-filter.component.html',
|
||||||
animations: [slide]
|
animations: [slide],
|
||||||
})
|
})
|
||||||
|
|
||||||
export class SidebarFilterComponent implements OnInit {
|
export class SidebarFilterComponent implements OnInit {
|
||||||
@@ -51,4 +52,8 @@ export class SidebarFilterComponent implements OnInit {
|
|||||||
initialExpand() {
|
initialExpand() {
|
||||||
this.filterService.initialExpand(this.filter.name);
|
this.filterService.initialExpand(this.filter.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSelectedValues(): Observable<string[]> {
|
||||||
|
return this.filterService.getSelectedValuesForFilter(this.filter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,6 @@ import {
|
|||||||
SearchFilterToggleAction
|
SearchFilterToggleAction
|
||||||
} from './search-filter.actions';
|
} from './search-filter.actions';
|
||||||
import { hasValue, } from '../../../shared/empty.util';
|
import { hasValue, } from '../../../shared/empty.util';
|
||||||
import { Params } from '@angular/router';
|
|
||||||
import { SearchFilterConfig } from '../../search-service/search-filter-config.model';
|
import { SearchFilterConfig } from '../../search-service/search-filter-config.model';
|
||||||
import { SearchService } from '../../search-service/search.service';
|
import { SearchService } from '../../search-service/search.service';
|
||||||
import { RouteService } from '../../../shared/route.service';
|
import { RouteService } from '../../../shared/route.service';
|
||||||
@@ -30,14 +29,16 @@ export class SearchFilterService {
|
|||||||
return this.routeService.hasQueryParamWithValue(paramName, filterValue);
|
return this.routeService.hasQueryParamWithValue(paramName, filterValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFilterValueURL(filterConfig: SearchFilterConfig, value: string): Observable<Params> {
|
getQueryParamsWithout(filterConfig: SearchFilterConfig, value: string) {
|
||||||
return this.isFilterActive(filterConfig.paramName, value).flatMap((isActive) => {
|
|
||||||
if (isActive) {
|
|
||||||
return this.routeService.removeQueryParameterValue(filterConfig.paramName, value);
|
return this.routeService.removeQueryParameterValue(filterConfig.paramName, value);
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
getQueryParamsWith(filterConfig: SearchFilterConfig, value: string) {
|
||||||
return this.routeService.addQueryParameterValue(filterConfig.paramName, value);
|
return this.routeService.addQueryParameterValue(filterConfig.paramName, value);
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
getSelectedValuesForFilter(filterConfig: SearchFilterConfig): Observable<string[]> {
|
||||||
|
return this.routeService.getQueryParameterValues(filterConfig.paramName);
|
||||||
}
|
}
|
||||||
|
|
||||||
get searchLink() {
|
get searchLink() {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<h2>{{"search.filters.head" | translate}}</h2>
|
<h2>{{"search.filters.head" | translate}}</h2>
|
||||||
<div *ngIf="(filters | async).hasSucceeded">
|
<div *ngIf="(filters | async).hasSucceeded">
|
||||||
<div *ngFor="let filter of (filters | async).payload">
|
<div *ngFor="let filter of (filters | async).payload">
|
||||||
<ds-search-filter [filter]="filter"></ds-search-filter>
|
<ds-search-filter class="d-block mb-3 p-3" [filter]="filter"></ds-search-filter>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a class="btn btn-primary" [routerLink]="[getSearchLink()]" [queryParams]="getClearFiltersQueryParams()" role="button">{{"search.filters.reset" | translate}}</a>
|
<a class="btn btn-primary" [routerLink]="[getSearchLink()]" [queryParams]="getClearFiltersQueryParams()" role="button">{{"search.filters.reset" | translate}}</a>
|
@@ -1,4 +1,4 @@
|
|||||||
import { Component, Input } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { SearchService } from '../search-service/search.service';
|
import { SearchService } from '../search-service/search.service';
|
||||||
import { RemoteData } from '../../core/data/remote-data';
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
import { SearchFilterConfig } from '../search-service/search-filter-config.model';
|
import { SearchFilterConfig } from '../search-service/search-filter-config.model';
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
<div class="search-page row">
|
<div class="search-page row">
|
||||||
<ds-search-sidebar *ngIf="!(isMobileView | async)" class="col-3 sidebar-sm-sticky"
|
<ds-search-sidebar *ngIf="!(isMobileView | async)" class="col-3 sidebar-sm-sticky"
|
||||||
id="search-sidebar"
|
id="search-sidebar"
|
||||||
resultCount="{{(resultsRDObs | async)?.pageInfo?.totalElements}}"></ds-search-sidebar>
|
[resultCount]="(resultsRDObs | async)?.pageInfo?.totalElements"></ds-search-sidebar>
|
||||||
<div class="col-12 col-sm-9">
|
<div class="col-12 col-sm-9">
|
||||||
<ds-search-form id="search-form"
|
<ds-search-form id="search-form"
|
||||||
[query]="query"
|
[query]="query"
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
[@pushInOut]="(isSidebarCollapsed() | async) ? 'collapsed' : 'expanded'">
|
[@pushInOut]="(isSidebarCollapsed() | async) ? 'collapsed' : 'expanded'">
|
||||||
<ds-search-sidebar *ngIf="(isMobileView | async)" class="col-12"
|
<ds-search-sidebar *ngIf="(isMobileView | async)" class="col-12"
|
||||||
id="search-sidebar-xs"
|
id="search-sidebar-xs"
|
||||||
resultCount="{{(results | async)?.pageInfo.totalElements}}"
|
[resultCount]="(resultsRDObs | async)?.pageInfo?.totalElements"
|
||||||
(toggleSidebar)="closeSidebar()"
|
(toggleSidebar)="closeSidebar()"
|
||||||
[ngClass]="{'active': !(isSidebarCollapsed() | async)}">
|
[ngClass]="{'active': !(isSidebarCollapsed() | async)}">
|
||||||
</ds-search-sidebar>
|
</ds-search-sidebar>
|
||||||
@@ -37,3 +37,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -90,7 +90,6 @@ export class SearchPageComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private updateSearchResults(searchOptions) {
|
private updateSearchResults(searchOptions) {
|
||||||
// Resolve search results
|
|
||||||
this.resultsRDObs = this.service.search(this.query, this.scope, searchOptions);
|
this.resultsRDObs = this.service.search(this.query, this.scope, searchOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@ export class SearchFilterConfig {
|
|||||||
name: string;
|
name: string;
|
||||||
type: FilterType;
|
type: FilterType;
|
||||||
hasFacets: boolean;
|
hasFacets: boolean;
|
||||||
pageSize = 3;
|
pageSize = 2;
|
||||||
isOpenByDefault: boolean;
|
isOpenByDefault: boolean;
|
||||||
/**
|
/**
|
||||||
* Name of this configuration that can be used in a url
|
* Name of this configuration that can be used in a url
|
||||||
|
@@ -15,6 +15,7 @@ import { FilterType } from './filter-type.model';
|
|||||||
import { FacetValue } from './facet-value.model';
|
import { FacetValue } from './facet-value.model';
|
||||||
import { ViewMode } from '../../+search-page/search-options.model';
|
import { ViewMode } from '../../+search-page/search-options.model';
|
||||||
import { Router, NavigationExtras, ActivatedRoute, Params } from '@angular/router';
|
import { Router, NavigationExtras, ActivatedRoute, Params } from '@angular/router';
|
||||||
|
import { RouteService } from '../../shared/route.service';
|
||||||
|
|
||||||
function shuffle(array: any[]) {
|
function shuffle(array: any[]) {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
@@ -81,6 +82,7 @@ export class SearchService implements OnDestroy {
|
|||||||
];
|
];
|
||||||
|
|
||||||
constructor(private itemDataService: ItemDataService,
|
constructor(private itemDataService: ItemDataService,
|
||||||
|
private routeService: RouteService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private router: Router) {
|
private router: Router) {
|
||||||
|
|
||||||
@@ -182,24 +184,26 @@ export class SearchService implements OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getFacetValuesFor(searchFilterConfigName: string): Observable<RemoteData<FacetValue[]>> {
|
getFacetValuesFor(searchFilterConfigName: string): Observable<RemoteData<FacetValue[]>> {
|
||||||
|
|
||||||
const filterConfig = this.config.find((config: SearchFilterConfig) => config.name === searchFilterConfigName);
|
const filterConfig = this.config.find((config: SearchFilterConfig) => config.name === searchFilterConfigName);
|
||||||
|
return this.routeService.getQueryParameterValues(filterConfig.paramName).map((selectedValues: string[]) => {
|
||||||
const values: FacetValue[] = [];
|
const values: FacetValue[] = [];
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
const value = searchFilterConfigName + ' ' + (i + 1);
|
const value = searchFilterConfigName + ' ' + (i + 1);
|
||||||
|
if (!selectedValues.includes(value)) {
|
||||||
values.push({
|
values.push({
|
||||||
value: value,
|
value: value,
|
||||||
count: Math.floor(Math.random() * 20) + 20 * (5 - i), // make sure first results have the highest (random) count
|
count: Math.floor(Math.random() * 20) + 20 * (5 - i), // make sure first results have the highest (random) count
|
||||||
search: decodeURI(this.router.url) + (this.router.url.includes('?') ? '&' : '?') + filterConfig.paramName + '=' + value
|
search: decodeURI(this.router.url) + (this.router.url.includes('?') ? '&' : '?') + filterConfig.paramName + '=' + value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
const requestPending = false;
|
const requestPending = false;
|
||||||
const responsePending = false;
|
const responsePending = false;
|
||||||
const isSuccessful = true;
|
const isSuccessful = true;
|
||||||
const errorMessage = undefined;
|
const errorMessage = undefined;
|
||||||
const statusCode = '200';
|
const statusCode = '200';
|
||||||
const returningPageInfo = new PageInfo();
|
const returningPageInfo = new PageInfo();
|
||||||
return Observable.of(new RemoteData(
|
return new RemoteData(
|
||||||
'https://dspace7.4science.it/dspace-spring-rest/api/search',
|
'https://dspace7.4science.it/dspace-spring-rest/api/search',
|
||||||
requestPending,
|
requestPending,
|
||||||
responsePending,
|
responsePending,
|
||||||
@@ -208,13 +212,15 @@ export class SearchService implements OnDestroy {
|
|||||||
statusCode,
|
statusCode,
|
||||||
returningPageInfo,
|
returningPageInfo,
|
||||||
values
|
values
|
||||||
));
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
getViewMode(): Observable<ViewMode> {
|
getViewMode(): Observable<ViewMode> {
|
||||||
return this.route.queryParams.map((params) => {
|
return this.routeService.getQueryParameterValue('view').map((value) => {
|
||||||
if (isNotEmpty(params.view) && hasValue(params.view)) {
|
if (hasValue(value)) {
|
||||||
return params.view;
|
return value as ViewMode;
|
||||||
} else {
|
} else {
|
||||||
return ViewMode.List;
|
return ViewMode.List;
|
||||||
}
|
}
|
||||||
|
@@ -5,4 +5,7 @@
|
|||||||
.results {
|
.results {
|
||||||
line-height: $button-height;
|
line-height: $button-height;
|
||||||
}
|
}
|
||||||
|
ds-view-mode-switch {
|
||||||
|
margin-bottom: $spacer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,7 @@ import { ServerResponseService } from '../shared/server-response.service';
|
|||||||
import { NativeWindowFactory, NativeWindowService } from '../shared/window.service';
|
import { NativeWindowFactory, NativeWindowService } from '../shared/window.service';
|
||||||
import { BrowseService } from './browse/browse.service';
|
import { BrowseService } from './browse/browse.service';
|
||||||
import { BrowseResponseParsingService } from './data/browse-response-parsing.service';
|
import { BrowseResponseParsingService } from './data/browse-response-parsing.service';
|
||||||
|
import { RouteService } from '../shared/route.service';
|
||||||
|
|
||||||
const IMPORTS = [
|
const IMPORTS = [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
@@ -65,6 +66,7 @@ const PROVIDERS = [
|
|||||||
ServerResponseService,
|
ServerResponseService,
|
||||||
BrowseResponseParsingService,
|
BrowseResponseParsingService,
|
||||||
BrowseService,
|
BrowseService,
|
||||||
|
RouteService,
|
||||||
{ provide: NativeWindowService, useFactory: NativeWindowFactory }
|
{ provide: NativeWindowService, useFactory: NativeWindowFactory }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { animate, state, transition, trigger, style } from '@angular/animations';
|
import { animate, state, transition, trigger, style, stagger, query } from '@angular/animations';
|
||||||
|
|
||||||
export const slide = trigger('slide', [
|
export const slide = trigger('slide', [
|
||||||
|
|
||||||
@@ -6,5 +6,5 @@ export const slide = trigger('slide', [
|
|||||||
|
|
||||||
state('collapsed', style({ height: 0 })),
|
state('collapsed', style({ height: 0 })),
|
||||||
|
|
||||||
transition('expanded <=> collapsed', animate(250)),
|
transition('expanded <=> collapsed', animate(250))
|
||||||
]);
|
]);
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { Injectable, OnDestroy } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { ActivatedRoute, convertToParamMap, Params, } from '@angular/router';
|
import { ActivatedRoute, convertToParamMap, Params, } from '@angular/router';
|
||||||
import { isNotEmpty } from './empty.util';
|
import { isNotEmpty } from './empty.util';
|
||||||
@@ -9,6 +9,14 @@ export class RouteService {
|
|||||||
constructor(private route: ActivatedRoute) {
|
constructor(private route: ActivatedRoute) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getQueryParameterValues(paramName: string): Observable<string[]> {
|
||||||
|
return this.route.queryParamMap.map((map) => map.getAll(paramName));
|
||||||
|
}
|
||||||
|
|
||||||
|
getQueryParameterValue(paramName: string): Observable<string> {
|
||||||
|
return this.route.queryParamMap.map((map) => map.get(paramName));
|
||||||
|
}
|
||||||
|
|
||||||
hasQueryParam(paramName: string): Observable<boolean> {
|
hasQueryParam(paramName: string): Observable<boolean> {
|
||||||
return this.route.queryParamMap.map((map) => {return map.has(paramName);});
|
return this.route.queryParamMap.map((map) => {return map.has(paramName);});
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user