[HIMA-59] - refactored state to allow for animating of selected filter

This commit is contained in:
Peter Skrlj
2019-02-13 08:14:46 +01:00
parent f54838603e
commit f381221bfe
9 changed files with 96 additions and 51 deletions

View File

@@ -21,7 +21,7 @@ export class FilterService {
if (filter.id === id) {
return { ...filter, expanded: true };
}
return { ...filter, expanded: false };
return { ...filter, expanded: false };
});
return of(newFilterState);
}

View File

@@ -18,13 +18,13 @@ export class LoadFullFilters {
export class SelectFilterById {
static readonly type = SELECT_FILTER_BY_ID;
constructor(public id: string, public payload: Filter[]) {}
constructor(public id: string) {}
}
export class UnselectFilterById {
static readonly type = UNSELECT_FILTER_BY_ID;
constructor(public id: string, public payload: Filter[]) {}
constructor(public id: string) {}
}
export class ToggleFilterItemById {
@@ -36,5 +36,5 @@ export class ToggleFilterItemById {
export class ToggleFilterItemByName {
static readonly type = TOGGLE_FILTER_ITEM_BY_NAME;
constructor(public name: string, public payload: Filter[]) {}
constructor(public name: string) {}
}

View File

@@ -1,5 +1,11 @@
import { Filter } from '../../models/filter.model';
import { State, Selector, Action, StateContext } from '@ngxs/store';
import {
State,
Selector,
Action,
StateContext,
createSelector
} from '@ngxs/store';
import {
LoadFilters,
LoadFullFilters,
@@ -29,6 +35,21 @@ export class FilterState {
return state.filters;
}
@Selector()
static getFilterCount(state: FilterStateModel) {
return state.filters.length;
}
static getFilterIndex(index: number) {
const val = index;
return createSelector(
[FilterState],
(state: FilterStateModel) => {
return state.filters[val];
}
);
}
@Selector()
static getFiltersJSON(state: FilterStateModel) {
return JSON.stringify(
@@ -66,15 +87,16 @@ export class FilterState {
@Action(SelectFilterById)
selectFilterById(
ctx: StateContext<FilterStateModel>,
{ id, payload }: SelectFilterById
{ id }: SelectFilterById
) {
const state = ctx.getState();
const filters = state.filters;
this.filterService
.selectFilterById(payload, id)
.selectFilterById(filters, id)
.subscribe((filters: Filter[]) => {
ctx.patchState({
...state,
filters: [...filters]
filters: filters
});
});
}
@@ -82,11 +104,12 @@ export class FilterState {
@Action(UnselectFilterById)
unselectFilterById(
ctx: StateContext<FilterStateModel>,
{ id, payload }: UnselectFilterById
{ id }: UnselectFilterById
) {
const state = ctx.getState();
const filters = state.filters;
this.filterService
.unselectFilterById(payload, id)
.unselectFilterById(filters, id)
.subscribe((filters: Filter[]) => {
ctx.patchState({
...state,
@@ -98,11 +121,13 @@ export class FilterState {
@Action(ToggleFilterItemById)
toggleItemById(
ctx: StateContext<FilterStateModel>,
{ id, payload }: ToggleFilterItemById
{ id }: ToggleFilterItemById
) {
const state = ctx.getState();
const filters = state.filters;
this.filterService
.toggleFilterItemsById(payload, id)
.toggleFilterItemsById(filters, id)
.subscribe((filters: Filter[]) => {
ctx.patchState({
...state,
@@ -114,11 +139,13 @@ export class FilterState {
@Action(ToggleFilterItemByName)
toggleItemByName(
ctx: StateContext<FilterStateModel>,
{ name, payload }: ToggleFilterItemByName
{ name }: ToggleFilterItemByName
) {
const state = ctx.getState();
const filters = state.filters;
this.filterService
.toggleFilterItemsByName(payload, name)
.toggleFilterItemsByName(filters, name)
.subscribe((filters: Filter[]) => {
ctx.patchState({
...state,

View File

@@ -2,17 +2,19 @@
<span class="filter-name">{{ filter.name }}</span>
<img
class="icon"
[ngClass]="{ hide: expanded }"
src="../../../assets/images/Arrow_Down_2.svg"
/>
<img
class="icon"
[ngClass]="{ hide: !expanded }"
src="../../../assets/images/Arrow_Down_5.svg"
[class.expand]="filter.expanded"
src="/assets/images/Arrow_Down_2.svg"
/>
</div>
<div class="filter-menu" [ngClass]="{ hide: !expanded }">
<div class="filter-menu" [class.hide]="!filter.expanded">
<div class="item-container">
<div class="item" (click)="selectItem(item)" [ngClass]="{'active': item.selected}" *ngFor="let item of filter.items">{{item.name}}</div>
<div
class="item"
(click)="selectItem(item)"
[class.active]="item.selected"
*ngFor="let item of filter.items"
>
{{ item.name }}
</div>
</div>
</div>

View File

@@ -9,6 +9,11 @@
.icon {
width: 17px;
margin-left: 5px;
transition: all 0.2s linear;
&.expand {
transform: rotate(-180deg);
}
}
.filter-item {

View File

@@ -1,3 +1,4 @@
import { FilterState } from 'src/app/core/store/state/filter.state';
import { Component, OnInit, Input } from '@angular/core';
import { Filter } from 'src/app/core/models/filter.model';
import {
@@ -7,6 +8,7 @@ import {
} from 'src/app/core/store/actions/filter.actions';
import { FilterItem } from 'src/app/core/models/filter-item.model';
import { Store } from '@ngxs/store';
import { map, take } from 'rxjs/operators';
@Component({
selector: 'app-filter-item',
@@ -15,25 +17,26 @@ import { Store } from '@ngxs/store';
})
export class FilterItemComponent implements OnInit {
@Input()
index: number;
filter: Filter;
@Input()
filters: Filter[];
@Input()
expanded: boolean;
constructor(private store: Store) {}
toggleMenu(id: string) {
const action = this.filter.expanded
? new UnselectFilterById(id, this.filters)
: new SelectFilterById(id, this.filters);
? new UnselectFilterById(id)
: new SelectFilterById(id);
this.store.dispatch(action);
}
selectItem(item: FilterItem) {
this.store.dispatch(new ToggleFilterItemByName(item.name, this.filters));
this.store.dispatch(new ToggleFilterItemByName(item.name));
}
ngOnInit() {
this.store.select(FilterState.getFilterIndex(this.index)).subscribe(f => {
this.filter = f;
});
}
}

View File

@@ -1,14 +1,14 @@
<div class="filter-container">
<app-filter-item *ngFor="let filter of filters"
[filter]="filter"
[filters]="filters"
[expanded]="filter.expanded"></app-filter-item>
<div *ngIf="!showMore" (click)="toggleMore()" class="more-filters-container">
<span class="more-filters">Mehr Filter</span>
<img class="more-icon" src="../../../assets/images/Arrow_More.svg">
<app-filter-item
*ngFor="let index of (filterIndexArray$ | async)"
[index]="index"
></app-filter-item>
<div (click)="toggleMore()" class="more-filters-container">
<span class="more-filters">{{ showMore ? 'Weniger' : 'Mehr' }} Filter</span>
<img
class="more-icon"
[class.more]="showMore"
src="/assets/images/Arrow_More.svg"
/>
</div>
<div *ngIf="showMore" (click)="toggleMore()" class="less-filters-container">
<img class="less-icon" src="../../../assets/images/Less_Arrow.svg">
<span class="less-filters">Weniger Filter</span>
</div>
</div>
</div>

View File

@@ -61,6 +61,7 @@
.more-icon {
width: 14px;
margin-left: 6px;
transition: all 0.2s linear;
}
.less-filters {
@@ -78,3 +79,7 @@
.less-icon {
width: 14px;
}
.more {
transform: translateX(-135px) rotate(-180deg);
}

View File

@@ -1,9 +1,13 @@
import { Component, OnInit } from '@angular/core';
import { Filter } from 'src/app/core/models/filter.model';
import { LoadFilters, LoadFullFilters } from 'src/app/core/store/actions/filter.actions';
import {
LoadFilters,
LoadFullFilters
} from 'src/app/core/store/actions/filter.actions';
import { Store, Select } from '@ngxs/store';
import { FilterState } from 'src/app/core/store/state/filter.state';
import { Observable } from 'rxjs';
import { map, distinctUntilChanged } from 'rxjs/operators';
@Component({
selector: 'app-filter',
@@ -11,19 +15,19 @@ import { Observable } from 'rxjs';
styleUrls: ['./filter.component.scss']
})
export class FilterComponent implements OnInit {
@Select(FilterState.getFilters) filters$: Observable<Filter[]>;
filters: Filter[];
@Select(FilterState.getFilterCount) filterCount$: Observable<number>;
filterIndexArray$: Observable<number[]>;
showMore: boolean;
constructor(private store: Store) { }
constructor(private store: Store) {}
ngOnInit() {
this.store.dispatch(new LoadFilters());
this.filters$.subscribe(
(filters: Filter[]) => this.filters = filters
);
this.showMore = false;
this.filterIndexArray$ = this.filterCount$.pipe(
distinctUntilChanged(),
map(c => Array.from(Array(c)).map((v, i) => i))
);
}
toggleMore() {
@@ -34,5 +38,4 @@ export class FilterComponent implements OnInit {
this.store.dispatch(new LoadFilters());
}
}
}