Commit 3d59078d authored by Exbrayat Cédric's avatar Exbrayat Cédric Committed by Exbrayat Cédric
Browse files

feat: responsive filters

parent ba3fd067
......@@ -23,6 +23,7 @@
"@ng-bootstrap/ng-bootstrap": "2.2.0",
"bootstrap": "4.1.3",
"core-js": "2.5.7",
"font-awesome": "4.7.0",
"rxjs": "6.2.2",
"zone.js": "0.8.26"
},
......
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LOCALE_ID, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';
......@@ -31,6 +32,7 @@ registerLocaleData(localeFr);
PillarsComponent
],
imports: [
BrowserAnimationsModule,
BrowserModule,
RouterModule.forRoot(routes),
ReactiveFormsModule,
......
......@@ -10,8 +10,14 @@
</div>
</form>
</div>
<div class="row mt-5">
<div class="col-lg-3 col-md-4 col-xs-12">
<div class="mt-3 mb-3 d-md-none">
<button class="btn btn-outline-secondary" (click)="toggleFilters()">
<i class="fa fa-sliders" aria-hidden="true"></i>&ngsp;Filtres&ngsp;
<i class="fa" [class.fa-caret-up]="filters === 'show'" [class.fa-caret-down]="filters === 'hide'" aria-hidden="true"></i>
</button>
</div>
<div class="row mt-sm-2 mt-md-5">
<div class="col-lg-3 col-md-4 col-xs-12 filters" [@showHide]="filters">
<!-- aggregations -->
<rare-aggregations *ngIf="aggregations"
[aggregations]="aggregations"
......
@import "node_modules/bootstrap/scss/functions";
@import "node_modules/bootstrap/scss/variables";
@import "node_modules/bootstrap/scss/mixins";
@include media-breakpoint-down(sm) {
.filters {
padding-top: 2px;
overflow-y: hidden;
}
}
......@@ -4,6 +4,7 @@ import { RouterTestingModule } from '@angular/router/testing';
import { Router } from '@angular/router';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { NgbPagination, NgbPaginationModule, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
import { of } from 'rxjs';
import { ComponentTester, fakeRoute, speculoosMatchers } from 'ngx-speculoos';
......@@ -50,7 +51,8 @@ describe('SearchComponent', () => {
RouterTestingModule,
HttpClientTestingModule,
NgbPaginationModule.forRoot(),
NgbTypeaheadModule.forRoot()
NgbTypeaheadModule.forRoot(),
NoopAnimationsModule
],
declarations: [SearchComponent, GeneticResourcesComponent, GeneticResourceComponent, AggregationsComponent, AggregationComponent]
}));
......@@ -238,6 +240,27 @@ describe('SearchComponent', () => {
});
});
it('should toggle filters', () => {
// given a component
const router = TestBed.get(Router) as Router;
const searchService = TestBed.get(SearchService) as SearchService;
const activatedRoute = fakeRoute({});
const component = new SearchComponent(activatedRoute, router, searchService);
expect(component.filters).toBe('hide');
// when toggling filters
component.toggleFilters();
// then it should show the filters
expect(component.filters).toBe('show');
// when toggling filters again
component.toggleFilters();
// then it should hide the filters
expect(component.filters).toBe('hide');
});
it('should display a search bar and trigger a search', () => {
// given a component
const tester = new SearchComponentTester();
......
......@@ -8,11 +8,32 @@ import { SearchService } from '../search.service';
import { GeneticResourceModel } from '../models/genetic-resource.model';
import { Aggregation, Page } from '../models/page';
import { AggregationCriterion } from '../models/aggregation-criterion';
import { animate, state, style, transition, trigger } from '@angular/animations';
@Component({
selector: 'rare-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.scss']
styleUrls: ['./search.component.scss'],
animations: [
/**
* Animation triggered when the filters are show/hidden
* on small devices.
*/
trigger('showHide', [
state('show', style({
height: '*'
})),
state('hide', style({
height: 0
})),
transition('show => hide', [
animate('500ms ease-out')
]),
transition('hide => show', [
animate('500ms ease-in')
])
])
]
})
export class SearchComponent implements OnInit {
query = '';
......@@ -22,6 +43,8 @@ export class SearchComponent implements OnInit {
aggregations: Array<Aggregation> = [];
// array of all the selected criteria
aggregationCriteria: Array<AggregationCriterion> = [];
// hide or show the filters on small devices
filters: 'show' | 'hide' = 'hide';
constructor(private route: ActivatedRoute, private router: Router, private searchService: SearchService) {
this.searchForm = new FormGroup({
......@@ -116,6 +139,10 @@ export class SearchComponent implements OnInit {
this.search({ query: this.query, criteria: this.aggregationCriteria });
}
toggleFilters() {
this.filters = this.filters === 'show' ? 'hide' : 'show';
}
/**
* Internal method called to update the URL with the new parameters (query, page, criteria).
* It accepts a search options object with one mandatory field (the query) and optional ones (page, criteria)
......
......@@ -19,20 +19,20 @@
*/
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
// import 'core-js/es6/symbol';
// import 'core-js/es6/object';
// import 'core-js/es6/function';
// import 'core-js/es6/parse-int';
// import 'core-js/es6/parse-float';
// import 'core-js/es6/number';
// import 'core-js/es6/math';
// import 'core-js/es6/string';
// import 'core-js/es6/date';
// import 'core-js/es6/array';
// import 'core-js/es6/regexp';
// import 'core-js/es6/map';
// import 'core-js/es6/weak-map';
// import 'core-js/es6/set';
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
......
$fa-font-path: '../node_modules/font-awesome/fonts';
@import '../node_modules/font-awesome/scss/font-awesome';
@import 'custom-bootstrap';
......@@ -2405,6 +2405,10 @@ follow-redirects@^1.0.0:
dependencies:
debug "^3.1.0"
font-awesome@4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133"
for-in@^0.1.3:
version "0.1.8"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment