From aec5da15dfcaccda7ecac3d927170da0de4fac96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Mon, 17 Jun 2024 12:18:25 +0300 Subject: [PATCH] Simple popup filter --- src/lib/filtering/index.ts | 1 + .../simple-popup-filter.component.html | 53 +++++++++++++++ .../simple-popup-filter.component.scss | 24 +++++++ .../simple-popup-filter.component.ts | 67 +++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 src/lib/filtering/simple-popup-filter/simple-popup-filter.component.html create mode 100644 src/lib/filtering/simple-popup-filter/simple-popup-filter.component.scss create mode 100644 src/lib/filtering/simple-popup-filter/simple-popup-filter.component.ts diff --git a/src/lib/filtering/index.ts b/src/lib/filtering/index.ts index 75e5952..6e2c92f 100644 --- a/src/lib/filtering/index.ts +++ b/src/lib/filtering/index.ts @@ -11,3 +11,4 @@ export * from './models/nested-filter.model'; export * from './popup-filter/popup-filter.component'; export * from './quick-filters/quick-filters.component'; +export * from './simple-popup-filter/simple-popup-filter.component'; 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 new file mode 100644 index 0000000..4ff55ee --- /dev/null +++ b/src/lib/filtering/simple-popup-filter/simple-popup-filter.component.html @@ -0,0 +1,53 @@ + + + + + + + + + +
+ +
+ +
+ +
+
+
+
+
+
+
+ +
+
+ + {{ option.label }} + +
+
+
+
+
diff --git a/src/lib/filtering/simple-popup-filter/simple-popup-filter.component.scss b/src/lib/filtering/simple-popup-filter/simple-popup-filter.component.scss new file mode 100644 index 0000000..1ca41d8 --- /dev/null +++ b/src/lib/filtering/simple-popup-filter/simple-popup-filter.component.scss @@ -0,0 +1,24 @@ +@use 'common-mixins'; + +.filter-menu-options, +.filter-menu-header { + display: flex; + justify-content: space-between; + padding: 8px 16px 16px 16px; + min-width: var(--filter-card-min-width); + + .actions { + display: flex; + gap: 8px; + } +} + +.input-wrapper { + padding: 0 8px 8px 8px; +} + +.filter-content { + max-height: 300px; + overflow: auto; + @include common-mixins.scroll-bar; +} 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 new file mode 100644 index 0000000..765990b --- /dev/null +++ b/src/lib/filtering/simple-popup-filter/simple-popup-filter.component.ts @@ -0,0 +1,67 @@ +import { Component, computed, 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 { StopPropagationDirective } from '../../directives'; +import { InputWithActionComponent } from '../../inputs'; + +@Component({ + selector: 'iqser-simple-popup-filter', + templateUrl: './simple-popup-filter.component.html', + styleUrls: ['./simple-popup-filter.component.scss'], + standalone: true, + imports: [ + CommonModule, + MatMenuModule, + IconButtonComponent, + ChevronButtonComponent, + StopPropagationDirective, + InputWithActionComponent, + TranslateModule, + MatCheckbox, + IconButtonComponent, + ChevronButtonComponent, + ], +}) +export class SimplePopupFilterComponent { + options = input.required(); + icon = input(); + label = input(); + filterPlaceholder = input.required(); + disabled = input(false); + selectionChanged = output(); + + readonly expanded = signal(false); + readonly selectedOptions = signal([]); + readonly hasActiveFilters = computed(() => this.selectedOptions().length > 0); + readonly searchValue = signal(''); + readonly displayedOptions = computed(() => + this.options().filter(option => option.label.toLowerCase().includes(this.searchValue().toLowerCase())), + ); + + constructor() { + toObservable(this.selectedOptions) + .pipe(takeUntilDestroyed()) + // eslint-disable-next-line rxjs/no-ignored-subscription + .subscribe(() => this.selectionChanged.emit(this.selectedOptions())); + } + + protected _selectAll(): void { + this.selectedOptions.set(untracked(this.options)); + } + + protected _clear(): void { + this.selectedOptions.set([]); + } + + protected _filterCheckboxClicked(option: T): void { + if (this.selectedOptions().includes(option)) { + this.selectedOptions.set(this.selectedOptions().filter(selectedOption => selectedOption !== option)); + } else { + this.selectedOptions.set([...this.selectedOptions(), option]); + } + } +}