diff --git a/src/assets/icons/filter-list.svg b/src/assets/icons/filter-list.svg new file mode 100644 index 0000000..914e2ad --- /dev/null +++ b/src/assets/icons/filter-list.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/lib/filtering/models/simple-filter-option.ts b/src/lib/filtering/models/simple-filter-option.ts new file mode 100644 index 0000000..3feee31 --- /dev/null +++ b/src/lib/filtering/models/simple-filter-option.ts @@ -0,0 +1,4 @@ +export interface SimpleFilterOption { + value: T; + label: string; +} diff --git a/src/lib/filtering/simple-popup-filter/simple-popup-filter.component.html b/src/lib/filtering/simple-popup-filter/simple-popup-filter.component.html index 4ff55ee..e8d52be 100644 --- a/src/lib/filtering/simple-popup-filter/simple-popup-filter.component.html +++ b/src/lib/filtering/simple-popup-filter/simple-popup-filter.component.html @@ -1,25 +1,33 @@ - - - + - - - + + +
diff --git a/src/lib/filtering/simple-popup-filter/simple-popup-filter.component.ts b/src/lib/filtering/simple-popup-filter/simple-popup-filter.component.ts index 765990b..5f85505 100644 --- a/src/lib/filtering/simple-popup-filter/simple-popup-filter.component.ts +++ b/src/lib/filtering/simple-popup-filter/simple-popup-filter.component.ts @@ -1,12 +1,12 @@ -import { Component, computed, input, output, signal, untracked } from '@angular/core'; +import { Component, computed, effect, input, output, signal, untracked } from '@angular/core'; import { MatMenuModule } from '@angular/material/menu'; import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; import { MatCheckbox } from '@angular/material/checkbox'; -import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'; -import { ChevronButtonComponent, IconButtonComponent } from '../../buttons'; +import { ChevronButtonComponent, CircleButtonComponent, IconButtonComponent } from '../../buttons'; import { StopPropagationDirective } from '../../directives'; import { InputWithActionComponent } from '../../inputs'; +import { SimpleFilterOption } from '../models/simple-filter-option'; @Component({ selector: 'iqser-simple-popup-filter', @@ -24,18 +24,20 @@ import { InputWithActionComponent } from '../../inputs'; MatCheckbox, IconButtonComponent, ChevronButtonComponent, + CircleButtonComponent, ], }) -export class SimplePopupFilterComponent { - options = input.required(); - icon = input(); - label = input(); - filterPlaceholder = input.required(); - disabled = input(false); - selectionChanged = output(); +export class SimplePopupFilterComponent { + readonly options = input.required[]>(); + readonly icon = input(); + readonly label = input(); + readonly filterPlaceholder = input.required(); + readonly disabled = input(false); + readonly type = input<'text' | 'icon'>('text'); + readonly selectionChanged = output[]>(); readonly expanded = signal(false); - readonly selectedOptions = signal([]); + readonly selectedOptions = signal[]>([]); readonly hasActiveFilters = computed(() => this.selectedOptions().length > 0); readonly searchValue = signal(''); readonly displayedOptions = computed(() => @@ -43,10 +45,24 @@ export class SimplePopupFilterComponent { ); constructor() { - toObservable(this.selectedOptions) - .pipe(takeUntilDestroyed()) - // eslint-disable-next-line rxjs/no-ignored-subscription - .subscribe(() => this.selectionChanged.emit(this.selectedOptions())); + effect(() => { + this.selectionChanged.emit(this.selectedOptions()); + }); + + /** If the options change and the selected options are not in the new options, remove them. */ + effect( + () => { + const allOptions = this.options(); + const selectedOptions = untracked(this.selectedOptions); + + if (selectedOptions.some(selectedOption => !allOptions.find(o => o.value === selectedOption))) { + this.selectedOptions.set( + selectedOptions.filter(selectedOption => allOptions.find(o => o.value === selectedOption.value)), + ); + } + }, + { allowSignalWrites: true }, + ); } protected _selectAll(): void { @@ -57,7 +73,7 @@ export class SimplePopupFilterComponent { this.selectedOptions.set([]); } - protected _filterCheckboxClicked(option: T): void { + protected _filterCheckboxClicked(option: SimpleFilterOption): void { if (this.selectedOptions().includes(option)) { this.selectedOptions.set(this.selectedOptions().filter(selectedOption => selectedOption !== option)); } else { diff --git a/src/lib/utils/constants.ts b/src/lib/utils/constants.ts index 4335e61..b1e2bc5 100644 --- a/src/lib/utils/constants.ts +++ b/src/lib/utils/constants.ts @@ -15,6 +15,7 @@ export const ICONS = new Set([ 'edit', 'expand', 'failure', + 'filter-list', 'help-outline', 'lanes', 'list',