mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
[HIMA-29] Implemented filter logic with filter backend API
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
|
||||
.menu-grid {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto auto auto;
|
||||
grid-template-columns: 20% 20% 20% 20% 20%;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ export class FilterItemMapping {
|
||||
|
||||
fromOptionDto(option: OptionDTO): FilterItem {
|
||||
return {
|
||||
id: option.key,
|
||||
id: option.value,
|
||||
name: option.label,
|
||||
selected: false
|
||||
};
|
||||
|
||||
@@ -47,6 +47,17 @@ export class FilterService {
|
||||
return of(newFilterState);
|
||||
}
|
||||
|
||||
toggleFilterItemsByName(filters: Filter[], name: string): Observable<Filter[]> {
|
||||
const newFilterState = filters.map((filter: Filter) => {
|
||||
if (filter.expanded === true) {
|
||||
const newItemsState = this.toggleItemByName(filter.items, name);
|
||||
return { ...filter, items: newItemsState };
|
||||
}
|
||||
return { ...filter };
|
||||
});
|
||||
return of(newFilterState);
|
||||
}
|
||||
|
||||
private toggleItem(items: FilterItem[], id: string): FilterItem[] {
|
||||
return items.map((item: FilterItem) => {
|
||||
if (item.id === id) {
|
||||
@@ -56,6 +67,15 @@ export class FilterService {
|
||||
});
|
||||
}
|
||||
|
||||
private toggleItemByName(items: FilterItem[], name: string): FilterItem[] {
|
||||
return items.map((item: FilterItem) => {
|
||||
if (item.name === name) {
|
||||
return { ...item, selected: !item.selected };
|
||||
}
|
||||
return { ...item };
|
||||
});
|
||||
}
|
||||
|
||||
// service method to get the first 3 filters
|
||||
getFilters(): Observable<Filter[]> {
|
||||
return this.service.settings().pipe(
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from 'cat-service';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Search } from '../models/search.model';
|
||||
import { FilterMapping } from '../mappings/filter.mapping';
|
||||
|
||||
|
||||
@Injectable({
|
||||
@@ -22,7 +23,8 @@ export class ProductService {
|
||||
searchResponse$: Observable<PagedApiResponse<ItemDTO>>;
|
||||
|
||||
constructor(
|
||||
private searchService: CatSearchService
|
||||
private searchService: CatSearchService,
|
||||
private filterMapping: FilterMapping
|
||||
) { }
|
||||
|
||||
persistLastSearchToLocalStorage(param: string) {
|
||||
@@ -70,7 +72,8 @@ export class ProductService {
|
||||
take: search.take
|
||||
};
|
||||
|
||||
return this.searchService.search(queryToken).pipe(
|
||||
const queryWithFilters = this.filterMapping.toQueryTokenDto(queryToken, search.fitlers);
|
||||
return this.searchService.search(queryWithFilters).pipe(
|
||||
map(response => {
|
||||
if (response.error) {
|
||||
throw new Error(response.message);
|
||||
|
||||
@@ -5,6 +5,7 @@ export const LOAD_FULL_FILTERS = '[FILTERS] Load full';
|
||||
export const SELECT_FILTER_BY_ID = '[FILTERS] Select by id';
|
||||
export const UNSELECT_FILTER_BY_ID = '[FILTERS] Unselect by id';
|
||||
export const TOGGLE_FILTER_ITEM_BY_ID = '[FILTERS] Toggle item by id';
|
||||
export const TOGGLE_FILTER_ITEM_BY_NAME = '[FILTERS] Toggle item by name';
|
||||
|
||||
export class LoadFilters {
|
||||
static readonly type = LOAD_FILTERS;
|
||||
@@ -31,3 +32,9 @@ export class ToggleFilterItemById {
|
||||
|
||||
constructor(public id: string, public payload: Filter[]) {}
|
||||
}
|
||||
|
||||
export class ToggleFilterItemByName {
|
||||
static readonly type = TOGGLE_FILTER_ITEM_BY_NAME;
|
||||
|
||||
constructor(public name: string, public payload: Filter[]) {}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import { Filter } from '../../models/filter.model';
|
||||
import { State, Selector, Action, StateContext } from '@ngxs/store';
|
||||
import { LoadFilters, LoadFullFilters, SelectFilterById, UnselectFilterById, ToggleFilterItemById } from '../actions/filter.actions';
|
||||
import {
|
||||
LoadFilters,
|
||||
LoadFullFilters,
|
||||
SelectFilterById,
|
||||
UnselectFilterById,
|
||||
ToggleFilterItemById,
|
||||
ToggleFilterItemByName
|
||||
} from '../actions/filter.actions';
|
||||
import { load } from '@angular/core/src/render3';
|
||||
import { FilterService } from '../../services/filter.service';
|
||||
|
||||
@@ -16,13 +23,18 @@ export class FilterStateModel {
|
||||
})
|
||||
export class FilterState {
|
||||
|
||||
constructor(private filterService: FilterService) {}
|
||||
constructor(private filterService: FilterService) { }
|
||||
|
||||
@Selector()
|
||||
static getFilters(state: FilterStateModel) {
|
||||
return state.filters;
|
||||
}
|
||||
|
||||
@Selector()
|
||||
static getSelectedFilters(state: FilterStateModel) {
|
||||
return state.filters.filter(f => f.items.find(i => i.selected === true));
|
||||
}
|
||||
|
||||
@Action(LoadFilters)
|
||||
load(ctx: StateContext<FilterStateModel>) {
|
||||
const state = ctx.getState();
|
||||
@@ -87,4 +99,17 @@ export class FilterState {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Action(ToggleFilterItemByName)
|
||||
toggleItemByName(ctx: StateContext<FilterStateModel>, { name, payload }: ToggleFilterItemByName) {
|
||||
const state = ctx.getState();
|
||||
this.filterService.toggleFilterItemsByName(payload, name).subscribe(
|
||||
(filters: Filter[]) => {
|
||||
ctx.patchState({
|
||||
...state,
|
||||
filters: [...filters]
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Filter } from 'src/app/core/models/filter.model';
|
||||
import {
|
||||
SelectFilterById,
|
||||
UnselectFilterById,
|
||||
ToggleFilterItemById
|
||||
ToggleFilterItemByName
|
||||
} from 'src/app/core/store/actions/filter.actions';
|
||||
import { FilterItem } from 'src/app/core/models/filter-item.model';
|
||||
import { Store } from '@ngxs/store';
|
||||
@@ -31,8 +31,9 @@ export class FilterItemComponent implements OnInit {
|
||||
}
|
||||
|
||||
selectItem(item: FilterItem) {
|
||||
this.store.dispatch(new ToggleFilterItemById(item.id, this.filters));
|
||||
this.store.dispatch(new ToggleFilterItemByName(item.name, this.filters));
|
||||
}
|
||||
|
||||
ngOnInit() {}
|
||||
ngOnInit() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto auto;
|
||||
//grid-gap: 5vh;
|
||||
margin-top: 15px;
|
||||
margin-top: 5px;
|
||||
width: 80%;
|
||||
margin-left: 15%;
|
||||
line-height: 3;
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
} from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Select, Store } from '@ngxs/store';
|
||||
import { FilterState } from 'src/app/core/store/state/filter.state';
|
||||
|
||||
@Component({
|
||||
selector: 'app-text-search',
|
||||
@@ -41,6 +42,7 @@ export class TextSearchComponent implements OnInit, AfterViewInit {
|
||||
products: Product[];
|
||||
filters: Filter[];
|
||||
@Select(ProcessState.getProcesses) processes$: Observable<Process[]>;
|
||||
@Select(FilterState.getSelectedFilters) filters$: Observable<Filter[]>;
|
||||
processes: Process[];
|
||||
|
||||
@Input()
|
||||
@@ -62,7 +64,8 @@ export class TextSearchComponent implements OnInit, AfterViewInit {
|
||||
if (!this.searchParams) {
|
||||
return;
|
||||
}
|
||||
this.loadSelectedFilters();
|
||||
this.filters$.subscribe(f => this.filters = f);
|
||||
console.log(this.filters);
|
||||
const search = <Search>{
|
||||
query: this.searchParams,
|
||||
fitlers: this.filters,
|
||||
@@ -112,13 +115,6 @@ export class TextSearchComponent implements OnInit, AfterViewInit {
|
||||
.subscribe((data: any) => this.searchProductsHandler(data));
|
||||
}
|
||||
|
||||
loadSelectedFilters() {
|
||||
// TODO filter selected filters
|
||||
// this.store.select('filters').subscribe(
|
||||
// (data: Filter[]) => this.filters = data
|
||||
// );
|
||||
}
|
||||
|
||||
loadProcesses() {
|
||||
this.processes$.subscribe((data: Process[]) => (this.processes = data));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user