From fce007b848ace40018439adf126b9fb2d4fb2ab5 Mon Sep 17 00:00:00 2001 From: benjamin Date: Thu, 14 May 2026 16:44:49 +0200 Subject: [PATCH] optimize show filter --- .../shows/list/filter/filter.component.html | 6 +++-- .../shows/list/filter/filter.component.less | 6 ++++- .../shows/list/filter/filter.component.ts | 26 ++++++++++++++++++- .../modules/shows/list/list.component.html | 16 ++++++++++-- .../modules/shows/list/list.component.less | 25 ++++++++++++++++++ src/app/modules/shows/list/list.component.ts | 21 +++++++++++++++ 6 files changed, 94 insertions(+), 6 deletions(-) diff --git a/src/app/modules/shows/list/filter/filter.component.html b/src/app/modules/shows/list/filter/filter.component.html index 672e96d..6a4540a 100644 --- a/src/app/modules/shows/list/filter/filter.component.html +++ b/src/app/modules/shows/list/filter/filter.component.html @@ -36,7 +36,9 @@ Archiviert - - + @if (filterActive) { + Filter zurücksetzen + } + diff --git a/src/app/modules/shows/list/filter/filter.component.less b/src/app/modules/shows/list/filter/filter.component.less index 35af625..24e3c95 100644 --- a/src/app/modules/shows/list/filter/filter.component.less +++ b/src/app/modules/shows/list/filter/filter.component.less @@ -2,13 +2,17 @@ div[formGroup] { display: flex; flex-direction: column; - gap: 12px; + gap: var(--gap-m); } .third { gap: 0; } +mat-checkbox { + margin-bottom: var(--gap-m); +} + :host ::ng-deep .mat-mdc-form-field { width: 100%; } diff --git a/src/app/modules/shows/list/filter/filter.component.ts b/src/app/modules/shows/list/filter/filter.component.ts index 157170c..a6f508c 100644 --- a/src/app/modules/shows/list/filter/filter.component.ts +++ b/src/app/modules/shows/list/filter/filter.component.ts @@ -2,6 +2,7 @@ import {Component, DestroyRef, inject, Input} from '@angular/core'; import {KeyValue} from '@angular/common'; import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; import {FormBuilder, FormControl, FormGroup, ReactiveFormsModule} from '@angular/forms'; +import {faFilterCircleXmark} from '@fortawesome/free-solid-svg-icons'; import {FilterValues} from './filter-values'; import {Show} from '../../services/show'; import {ShowService} from '../../services/show.service'; @@ -15,14 +16,23 @@ import {MatSelect} from '@angular/material/select'; import {MatOptgroup, MatOption} from '@angular/material/core'; import {ShowTypePipe} from '../../../../widget-modules/pipes/show-type-translater/show-type.pipe'; import {MatCheckbox} from '@angular/material/checkbox'; +import {ButtonComponent} from '../../../../widget-modules/components/button/button.component'; + +const DEFAULT_SHOW_FILTER: FilterValues = { + time: 1, + owner: '', + showType: '', + archived: false, +}; @Component({ selector: 'app-filter', templateUrl: './filter.component.html', styleUrls: ['./filter.component.less'], - imports: [ReactiveFormsModule, MatFormField, MatLabel, MatSelect, MatOption, MatOptgroup, ShowTypePipe, MatCheckbox], + imports: [ReactiveFormsModule, MatFormField, MatLabel, MatSelect, MatOption, MatOptgroup, ShowTypePipe, MatCheckbox, ButtonComponent], }) export class FilterComponent { + public faResetFilter = faFilterCircleXmark; @Input() public shows: Show[] = []; public showTypePublic = ShowService.SHOW_TYPE_PUBLIC; public showTypePrivate = ShowService.SHOW_TYPE_PRIVATE; @@ -106,6 +116,20 @@ export class FilterComponent { ); }; + public get filterActive(): boolean { + const filter = this.filterFormGroup.getRawValue(); + return ( + filter.time !== DEFAULT_SHOW_FILTER.time || + !!filter.owner || + !!filter.showType || + filter.archived !== DEFAULT_SHOW_FILTER.archived + ); + } + + public resetFilter(): void { + this.filterStore.resetShowFilter(); + } + private filterValueChanged(key: keyof FilterValues, value: T): void { this.filterStore.updateShowFilter({[key]: value} as Partial); } diff --git a/src/app/modules/shows/list/list.component.html b/src/app/modules/shows/list/list.component.html index ebc2f7b..57cc186 100644 --- a/src/app/modules/shows/list/list.component.html +++ b/src/app/modules/shows/list/list.component.html @@ -1,11 +1,17 @@ @if (showSidebar$ | async) { - +
@if (privateShows$ | async; as privateShows) { + @if ((filterActive$ | async) ?? false) { +
+ Filter aktiv: {{ privateShows.length }} Veranstaltungen angezeigt. + +
+ } @for (show of privateShows; track trackBy($index, show)) { } @if (publicShows$ | async; as shows) { - @if (shows.length > 0) { + @if (shows.length > 0 || ((filterActive$ | async) ?? false)) { + @if ((filterActive$ | async) ?? false) { +
+ Filter aktiv: {{ shows.length }} Veranstaltungen angezeigt. + +
+ } @for (show of shows; track trackBy($index, show)) { } diff --git a/src/app/modules/shows/list/list.component.less b/src/app/modules/shows/list/list.component.less index ceee71e..ea93c4e 100644 --- a/src/app/modules/shows/list/list.component.less +++ b/src/app/modules/shows/list/list.component.less @@ -5,3 +5,28 @@ .list-action { margin: 10px 20px; } + +.filter-active { + padding: 10px 20px; + display: flex; + align-items: baseline; + gap: 10px; + flex-wrap: wrap; + color: var(--danger); + font-weight: bold; +} + +.filter-reset-link { + padding: 0; + border: 0; + background: transparent; + color: var(--link-color); + cursor: pointer; + font: inherit; + font-weight: normal; + text-decoration: underline; +} + +.filter-reset-link:hover { + color: var(--primary-active); +} diff --git a/src/app/modules/shows/list/list.component.ts b/src/app/modules/shows/list/list.component.ts index 1fff9ec..6bbf07a 100644 --- a/src/app/modules/shows/list/list.component.ts +++ b/src/app/modules/shows/list/list.component.ts @@ -17,6 +17,13 @@ import {ButtonComponent} from '../../../widget-modules/components/button/button. import {faPlus} from '@fortawesome/free-solid-svg-icons'; import {RoleDirective} from '../../../services/user/role.directive'; +const DEFAULT_SHOW_FILTER: FilterValues = { + time: 1, + owner: '', + showType: '', + archived: false, +}; + @Component({ selector: 'app-list', templateUrl: './list.component.html', @@ -28,6 +35,7 @@ export class ListComponent { public faNewShow = faPlus; private filterStore = inject(FilterStoreService); public filter$ = this.filterStore.showFilter$; + public filterActive$ = this.filter$.pipe(map(filter => this.isFilterActive(filter))); public lastMonths$ = this.filter$.pipe(map((filterValues: FilterValues) => filterValues.time || 1)); public owner$ = this.filter$.pipe(map((filterValues: FilterValues) => filterValues.owner)); public showType$ = this.filter$.pipe(map((filterValues: FilterValues) => filterValues.showType)); @@ -69,6 +77,10 @@ export class ListComponent { public trackBy = (index: number, show: unknown) => (show as Show).id; + public resetFilter(): void { + this.filterStore.resetShowFilter(); + } + private matchesTimeFilter(show: Show, lastMonths: number): boolean { const startDate = new Date(); startDate.setHours(0, 0, 0, 0); @@ -88,4 +100,13 @@ export class ListComponent { const roles = role.split(';').map(item => item.trim()); return roles.includes('admin') || roles.includes('leader'); } + + private isFilterActive(filter: FilterValues): boolean { + return ( + filter.time !== DEFAULT_SHOW_FILTER.time || + !!filter.owner || + !!filter.showType || + filter.archived !== DEFAULT_SHOW_FILTER.archived + ); + } }