mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
Merge branch 'fix/848-849-Filter-Reset-On-Unselected-Filters-And-PrimaryFilters-Not-Affects-Selected-Filters' into feature/189-Warenausgabe/277-Filter/main
This commit is contained in:
@@ -24,10 +24,6 @@ $font-size: 18px;
|
||||
}
|
||||
|
||||
.clear-all {
|
||||
&:only-child {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.filter-name {
|
||||
padding-right: $filter-padding-right;
|
||||
padding-left: 2rem;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
<app-selected-filter-options
|
||||
[value]="filters"
|
||||
(filterChanged)="onFiltersChange($event)"
|
||||
[showResetButton]="filters | hasSelectedFilters"
|
||||
>
|
||||
</app-selected-filter-options>
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { RemissionUeberlaufCapacitiesModule } from '../../pages/remission-list-create/ueberlauf-capacities';
|
||||
import { SharedModule } from 'apps/sales/src/app/shared/shared.module';
|
||||
import { RemissionRequiredCapacitiesWidgetModule } from '../../components/remission-required-capacities-widget';
|
||||
import { HasSelectedFiltersPipe } from '../../pipes';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -21,8 +22,8 @@ import { RemissionRequiredCapacitiesWidgetModule } from '../../components/remiss
|
||||
RemissionUeberlaufCapacitiesModule,
|
||||
RemissionRequiredCapacitiesWidgetModule,
|
||||
],
|
||||
exports: [RemissionListFilterComponent],
|
||||
declarations: [RemissionListFilterComponent],
|
||||
exports: [RemissionListFilterComponent, HasSelectedFiltersPipe],
|
||||
declarations: [RemissionListFilterComponent, HasSelectedFiltersPipe],
|
||||
entryComponents: [RemissionListFilterComponent],
|
||||
})
|
||||
export class RemissionListFilterModule {}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { HasSelectedFiltersPipe } from './has-selected-filters.pipe';
|
||||
import { filters } from '../mocks';
|
||||
|
||||
fdescribe('Pipe: HasSelectedFiltersPipe', () => {
|
||||
let pipe: HasSelectedFiltersPipe;
|
||||
|
||||
beforeEach(() => {
|
||||
pipe = new HasSelectedFiltersPipe();
|
||||
});
|
||||
|
||||
it('should return true', () => {
|
||||
const filterWithSelected = filters;
|
||||
|
||||
const result = pipe.transform(filterWithSelected);
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return false', () => {
|
||||
const filterWithSelected = filters.map((f) => ({
|
||||
...f,
|
||||
options: f.options.map((o) => ({ ...o, selected: false })),
|
||||
}));
|
||||
|
||||
const result = pipe.transform(filterWithSelected);
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { SelectFilter } from '../../filter';
|
||||
|
||||
@Pipe({
|
||||
name: 'hasSelectedFilters',
|
||||
})
|
||||
export class HasSelectedFiltersPipe implements PipeTransform {
|
||||
hasSelectedFilters = (filter: SelectFilter[]) => {
|
||||
return filter.some((f) => f.options.some((o) => o.selected));
|
||||
};
|
||||
|
||||
transform(filters: SelectFilter[]): boolean {
|
||||
return this.hasSelectedFilters(filters);
|
||||
}
|
||||
}
|
||||
4
apps/sales/src/app/modules/remission/pipes/index.ts
Normal file
4
apps/sales/src/app/modules/remission/pipes/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// start:ng42.barrel
|
||||
export * from './has-selected-filters.pipe';
|
||||
// end:ng42.barrel
|
||||
|
||||
@@ -3,6 +3,7 @@ import { SearchStateFacade } from '@shelf-store';
|
||||
import { ShelfFilterService } from './shelf-filter.service';
|
||||
import { mockFilters } from '../shared/mockdata';
|
||||
import { hot, cold } from 'jasmine-marbles';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
fdescribe('#ShelfFilterService', () => {
|
||||
let service: ShelfFilterService;
|
||||
@@ -16,11 +17,11 @@ fdescribe('#ShelfFilterService', () => {
|
||||
useValue: jasmine.createSpyObj('searchStateFacade', [
|
||||
'selectFilters$',
|
||||
'primaryFilterChangedFromDefault$',
|
||||
'selectFilters$',
|
||||
]),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
spyOn(
|
||||
ShelfFilterService.prototype,
|
||||
'initPendingFilters'
|
||||
@@ -28,12 +29,49 @@ fdescribe('#ShelfFilterService', () => {
|
||||
|
||||
facade = TestBed.get(SearchStateFacade);
|
||||
service = TestBed.get(ShelfFilterService);
|
||||
|
||||
spyOn(service, 'initService').and.callFake(() => {});
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
xdescribe('initPendingFilters', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(service.pendingFilters$, 'next').and.callFake(() => {});
|
||||
spyOn(service, 'lastFilterGroupChanged$').and.returnValue({
|
||||
next: new Subject(),
|
||||
});
|
||||
});
|
||||
|
||||
xit('should should update pending filters only when filters change for the first time', async () => {
|
||||
spyOnProperty(
|
||||
service,
|
||||
'pendingFiltersShouldUpdate$',
|
||||
'get'
|
||||
).and.callThrough();
|
||||
});
|
||||
|
||||
const filters$ = hot('-a---b---c|', {
|
||||
a: mockFilters,
|
||||
b: { ...mockFilters },
|
||||
c: { ...mockFilters },
|
||||
});
|
||||
((facade.selectFilters$ as unknown) as jasmine.Spy).and.returnValue(
|
||||
filters$
|
||||
);
|
||||
|
||||
const resetFilter$ = hot('-a', { a: true });
|
||||
spyOnProperty(service, 'resetFilters$', 'get').and.returnValue(
|
||||
resetFilter$
|
||||
);
|
||||
|
||||
const expected = hot('-a', { a: mockFilters });
|
||||
|
||||
expect(service.pendingFiltersShouldUpdate$).toBeObservable(expected);
|
||||
});
|
||||
|
||||
describe('#filtersChangedFromDefault', () => {
|
||||
beforeEach(() => {
|
||||
spyOnProperty(service, 'filtersChangedFromDefault$').and.callThrough();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
import { Observable, BehaviorSubject, Subject, combineLatest } from 'rxjs';
|
||||
import { SelectFilter, Filter, SelectFilterOption } from '../../filter';
|
||||
import { tap, startWith, map, filter, takeUntil } from 'rxjs/operators';
|
||||
import { tap, startWith, map, filter, takeUntil, take } from 'rxjs/operators';
|
||||
import { SearchStateFacade } from '../../../store/customer';
|
||||
import { flatten } from '../../../shared/utils';
|
||||
import { isNullOrUndefined } from 'util';
|
||||
@@ -20,8 +20,7 @@ export class ShelfFilterService implements OnDestroy {
|
||||
public overlayClosed$ = new Subject<void>();
|
||||
|
||||
constructor(private searchStateFacade: SearchStateFacade) {
|
||||
this.filters$ = this.searchStateFacade.selectFilters$;
|
||||
this.initPendingFilters();
|
||||
this.initService();
|
||||
}
|
||||
|
||||
get hasSelectedFilters$(): Observable<boolean> {
|
||||
@@ -55,19 +54,31 @@ export class ShelfFilterService implements OnDestroy {
|
||||
);
|
||||
}
|
||||
|
||||
get pendingFiltersShouldUpdate$() {
|
||||
return combineLatest([
|
||||
this.filters$.pipe(
|
||||
filter((filters) => !isNullOrUndefined(filters)),
|
||||
take(1)
|
||||
),
|
||||
this.resetFilters$.pipe(
|
||||
startWith(true),
|
||||
tap(() => this.pendingFilters$.next(null))
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
initService() {
|
||||
this.filters$ = this.searchStateFacade.selectFilters$;
|
||||
this.initPendingFilters();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
initPendingFilters() {
|
||||
combineLatest([
|
||||
this.filters$.pipe(filter((filters) => !isNullOrUndefined(filters))),
|
||||
this.resetFilters$.pipe(
|
||||
startWith(true),
|
||||
tap(() => this.pendingFilters$.next(null))
|
||||
),
|
||||
])
|
||||
this.pendingFiltersShouldUpdate$
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(([filters]) => {
|
||||
this.pendingFilters$.next(filters.map(cloneFilter));
|
||||
|
||||
Reference in New Issue
Block a user