[MNT-25412] Proper date filter clean up after reset event (#11317)

* [MNT-25412] Proper date filter clean up after reset event

* [MNT-25412] CR fixes

* [MNT-25412] Sonar issues fixed
This commit is contained in:
Michal Kinas
2025-11-12 09:36:58 +01:00
committed by GitHub
parent 0d670dd333
commit c2f4597309
6 changed files with 63 additions and 20 deletions

View File

@@ -26,11 +26,12 @@ before that release, please ensure that your component configuration is updated
### Properties
| Name | Type | Description |
|--------------|-----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|--------------|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| field | string | Field to apply the query to. Required value |
| maxDate | string | A fixed date (default format: dd-MMM-yy) or the string `"today"` that will set the maximum searchable date. Default is today. |
| dateFormat | string | Date format. Dates used by the datepicker are Javascript Date objects, using [date-fns](https://date-fns.org/v2.30.0/docs/format) for formatting, so you can use any date format supported by the library. Default is 'dd-MMM-yy (sample date - 07-Jun-23) |
| initialValue | SearchDateRange | Initial value for the component |
| onReset$ | [`Observable`](http://reactivex.io/documentation/observable.html)`<void>` | Reset event observable |
### Events

View File

@@ -6,6 +6,7 @@
[maxDate]="settings.maxDate"
[field]="field"
[initialValue]="preselectedValues[field]"
[onReset$]="reset$"
(changed)="onDateRangedValueChanged($event, field)"
(valid)="tabsValidity[field]=$event" />
</ng-container>

View File

@@ -225,16 +225,20 @@ describe('SearchDateRangeTabbedComponent', () => {
expect(component.context.update).toHaveBeenCalled();
});
it('should clear values and search filter when widget is reset', () => {
it('should clear values and search filter when widget is reset', (done) => {
spyOn(component.displayValue$, 'next');
component.reset();
fixture.detectChanges();
component.reset$.subscribe(() => {
expect(component.combinedQuery).toBe('');
expect(component.combinedDisplayValue).toBe('');
expect(component.displayValue$.next).toHaveBeenCalledWith('');
expect(component.context.queryFragments['dateRange']).toEqual('');
expect(component.context.update).toHaveBeenCalled();
component.fields.forEach((field) => expect(component.context.filterRawParams[field]).toBeUndefined());
done();
});
component.reset();
fixture.detectChanges();
});
it('should populate filter state when populate filters event has been observed', () => {

View File

@@ -16,7 +16,7 @@
*/
import { Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core';
import { ReplaySubject } from 'rxjs';
import { ReplaySubject, Subject } from 'rxjs';
import { map } from 'rxjs/operators';
import { DateRangeType } from './search-date-range/date-range-type';
import { SearchDateRange } from './search-date-range/search-date-range';
@@ -42,6 +42,13 @@ const DEFAULT_DATE_DISPLAY_FORMAT = 'dd-MMM-yy';
encapsulation: ViewEncapsulation.None
})
export class SearchDateRangeTabbedComponent implements SearchWidget, OnInit {
private value: { [key: string]: Partial<SearchDateRange> } = {};
private readonly queryMapByField = new Map<string, string>();
private readonly displayValueMapByField = new Map<string, string>();
private readonly destroyRef = inject(DestroyRef);
private readonly resetSubject$ = new Subject<void>();
displayValue$ = new ReplaySubject<string>(1);
id: string;
startValue: SearchDateRange = {
@@ -58,12 +65,7 @@ export class SearchDateRangeTabbedComponent implements SearchWidget, OnInit {
tabsValidity: { [key: string]: boolean } = {};
combinedQuery: string;
combinedDisplayValue: string;
private value: { [key: string]: Partial<SearchDateRange> } = {};
private queryMapByField: Map<string, string> = new Map<string, string>();
private displayValueMapByField: Map<string, string> = new Map<string, string>();
private readonly destroyRef = inject(DestroyRef);
reset$ = this.resetSubject$.asObservable();
constructor(private translateService: TranslationService) {}
@@ -121,6 +123,7 @@ export class SearchDateRangeTabbedComponent implements SearchWidget, OnInit {
this.context.queryFragments[this.id] = undefined;
this.context.filterRawParams[this.id] = undefined;
this.submitValues(updateContext);
this.resetSubject$.next();
}
setValue(value: { [key: string]: SearchDateRange }) {

View File

@@ -25,6 +25,7 @@ import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatCalendarHarness, MatDatepickerToggleHarness } from '@angular/material/datepicker/testing';
import { MatRadioButtonHarness } from '@angular/material/radio/testing';
import { Subject } from 'rxjs';
describe('SearchDateRangeComponent', () => {
let component: SearchDateRangeComponent;
@@ -33,6 +34,7 @@ describe('SearchDateRangeComponent', () => {
const startDateSampleValue = parse('05-Jun-23', 'dd-MMM-yy', new Date());
const endDateSampleValue = parse('07-Jun-23', 'dd-MMM-yy', new Date());
const resetSubject = new Subject<void>();
beforeEach(() => {
TestBed.configureTestingModule({
@@ -51,6 +53,7 @@ describe('SearchDateRangeComponent', () => {
betweenStartDate: null,
betweenEndDate: null
});
component.onReset$ = resetSubject.asObservable();
loader = TestbedHarnessEnvironment.documentRootLoader(fixture);
fixture.detectChanges();
});
@@ -296,4 +299,20 @@ describe('SearchDateRangeComponent', () => {
fixture.detectChanges();
expect(component.changed.emit).toHaveBeenCalledWith(value);
});
it('should reset the form when onReset event is received', () => {
spyOn(component, 'reset').and.callThrough();
component.form.controls.dateRangeType.setValue(component.DateRangeType.BETWEEN);
component.form.controls.betweenStartDate.setValue(startDateSampleValue);
component.form.controls.betweenEndDate.setValue(endDateSampleValue);
fixture.detectChanges();
resetSubject.next();
fixture.detectChanges();
expect(component.form.controls.dateRangeType.value).toEqual(component.DateRangeType.ANY);
expect(component.form.controls.betweenStartDate.value).toBeNull();
expect(component.form.controls.betweenEndDate.value).toBeNull();
expect(component.reset).toHaveBeenCalled();
});
});

View File

@@ -32,6 +32,7 @@ import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { Observable } from 'rxjs';
const DEFAULT_DATE_DISPLAY_FORMAT = 'dd-MMM-yy';
@@ -70,6 +71,9 @@ export class SearchDateRangeComponent implements OnInit {
}
}
@Input()
onReset$: Observable<void>;
@Output()
changed = new EventEmitter<Partial<SearchDateRange>>();
@Output()
@@ -118,6 +122,7 @@ export class SearchDateRangeComponent implements OnInit {
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((dateRangeType) => this.updateValidators(dateRangeType));
this.form.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.onChange());
this.onReset$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.reset());
}
private updateValidators(dateRangeType: DateRangeType) {
switch (dateRangeType) {
@@ -189,4 +194,14 @@ export class SearchDateRangeComponent implements OnInit {
return true;
}
}
reset(): void {
this.form.reset({
dateRangeType: DateRangeType.ANY,
inLastValueType: InLastDateType.DAYS,
inLastValue: undefined,
betweenStartDate: undefined,
betweenEndDate: undefined
});
}
}