optimize show filter
This commit is contained in:
@@ -36,7 +36,9 @@
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-checkbox formControlName="archived">Archiviert</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<!-- <i>Anzahl der Suchergebnisse: {{ shows?.length ?? 0 }}</i>-->
|
||||
@if (filterActive) {
|
||||
<app-button (click)="resetFilter()" [fullWidth]="true" [icon]="faResetFilter">Filter zurücksetzen</app-button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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%;
|
||||
}
|
||||
|
||||
@@ -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<T>(key: keyof FilterValues, value: T): void {
|
||||
this.filterStore.updateShowFilter({[key]: value} as Partial<FilterValues>);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
@if (showSidebar$ | async) {
|
||||
<app-page-frame title="Veranstaltungen">
|
||||
<app-page-frame title="Veranstaltungen" [menuBadge]="(filterActive$ | async) ?? false">
|
||||
<div class="sidebar-content" sidebar>
|
||||
<app-filter [shows]="(publicShows$ | async) ?? []"></app-filter>
|
||||
</div>
|
||||
<div content>
|
||||
@if (privateShows$ | async; as privateShows) {
|
||||
<app-card [padding]="false" heading="Meine Veranstaltungen">
|
||||
@if ((filterActive$ | async) ?? false) {
|
||||
<div class="filter-active">
|
||||
<span>Filter aktiv: {{ privateShows.length }} Veranstaltungen angezeigt.</span>
|
||||
<button (click)="resetFilter()" class="filter-reset-link" type="button">Filter zurücksetzen</button>
|
||||
</div>
|
||||
}
|
||||
@for (show of privateShows; track trackBy($index, show)) {
|
||||
<app-list-item
|
||||
[routerLink]="show.id"
|
||||
@@ -20,8 +26,14 @@
|
||||
</app-card>
|
||||
}
|
||||
@if (publicShows$ | async; as shows) {
|
||||
@if (shows.length > 0) {
|
||||
@if (shows.length > 0 || ((filterActive$ | async) ?? false)) {
|
||||
<app-card [padding]="false" heading="Veröffentlichte Veranstaltungen">
|
||||
@if ((filterActive$ | async) ?? false) {
|
||||
<div class="filter-active">
|
||||
<span>Filter aktiv: {{ shows.length }} Veranstaltungen angezeigt.</span>
|
||||
<button (click)="resetFilter()" class="filter-reset-link" type="button">Filter zurücksetzen</button>
|
||||
</div>
|
||||
}
|
||||
@for (show of shows; track trackBy($index, show)) {
|
||||
<app-list-item [routerLink]="show.id" [show]="show"></app-list-item>
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user