diff --git a/src/app/modules/shows/list/filter/filter-values.ts b/src/app/modules/shows/list/filter/filter-values.ts index 843abae..3b1f95d 100644 --- a/src/app/modules/shows/list/filter/filter-values.ts +++ b/src/app/modules/shows/list/filter/filter-values.ts @@ -1,3 +1,5 @@ export interface FilterValues { time: number; + owner: string; + showType: string; } diff --git a/src/app/modules/shows/list/filter/filter.component.html b/src/app/modules/shows/list/filter/filter.component.html index 3d73807..5a2fdd2 100644 --- a/src/app/modules/shows/list/filter/filter.component.html +++ b/src/app/modules/shows/list/filter/filter.component.html @@ -10,6 +10,34 @@ + + Ersteller + + {{ + owner.value + }} + + + + + + Art der Veranstaltung + + + {{ + key | showType + }} + + + + {{ + key | showType + }} + + + + + Anzahl der Suchergebnisse: {{ shows.length }} diff --git a/src/app/modules/shows/list/filter/filter.component.less b/src/app/modules/shows/list/filter/filter.component.less index 7d183ee..b172b2e 100644 --- a/src/app/modules/shows/list/filter/filter.component.less +++ b/src/app/modules/shows/list/filter/filter.component.less @@ -1,5 +1,5 @@ .third { display: grid; - grid-template-columns: 1fr 1fr 1fr 1fr; + grid-template-columns: 1fr 1fr 1fr; column-gap: 20px; } diff --git a/src/app/modules/shows/list/filter/filter.component.ts b/src/app/modules/shows/list/filter/filter.component.ts index b8663b6..7719d73 100644 --- a/src/app/modules/shows/list/filter/filter.component.ts +++ b/src/app/modules/shows/list/filter/filter.component.ts @@ -4,6 +4,12 @@ import {ActivatedRoute, Router} from '@angular/router'; import {UntypedFormBuilder, UntypedFormGroup} from '@angular/forms'; import {FilterValues} from './filter-values'; import {Show} from '../../services/show'; +import {ShowService} from '../../services/show.service'; +import {distinctUntilChanged, map} from 'rxjs/operators'; +import {combineLatest, Observable} from 'rxjs'; +import {dynamicSort, onlyUnique} from '../../../../services/filter.helper'; +import {UserService} from '../../../../services/user/user.service'; +import {isEqual} from 'lodash'; @Component({ selector: 'app-filter', @@ -14,6 +20,9 @@ export class FilterComponent { @Input() public route = '/shows/'; @Input() public shows: Show[] = []; + public showTypePublic = ShowService.SHOW_TYPE_PUBLIC; + public showTypePrivate = ShowService.SHOW_TYPE_PRIVATE; + public filterFormGroup: UntypedFormGroup; public times: KeyValue[] = [ {key: 1, value: 'letzter Monat'}, @@ -22,9 +31,19 @@ export class FilterComponent { {key: 99999, value: 'alle'}, ]; - public constructor(private router: Router, activatedRoute: ActivatedRoute, fb: UntypedFormBuilder) { + public owners: {key: string; value: string}[] = []; + + public constructor( + private router: Router, + private showService: ShowService, + private userService: UserService, + activatedRoute: ActivatedRoute, + fb: UntypedFormBuilder + ) { this.filterFormGroup = fb.group({ time: 1, + owner: null, + showType: null, }); activatedRoute.queryParams.subscribe(params => { @@ -33,8 +52,34 @@ export class FilterComponent { }); this.filterFormGroup.controls.time.valueChanges.subscribe(_ => void this.filerValueChanged('time', _ as number)); + this.filterFormGroup.controls.owner.valueChanges.subscribe(_ => void this.filerValueChanged('owner', _ as string)); + this.filterFormGroup.controls.showType.valueChanges.subscribe(_ => void this.filerValueChanged('showType', _ as string)); + + this.owners$().subscribe(owners => (this.owners = owners)); } + public owners$ = (): Observable<{key: string; value: string}[]> => { + return combineLatest([ + this.showService.list$().pipe( + map(shows => { + return shows.map(show => show.owner).filter(onlyUnique); + }) + ), + this.userService.users$, + ]).pipe( + map(([owners, users]) => { + return owners + .map(ownerId => ({ + key: ownerId, + value: users.find(user => user.id === ownerId)?.name, + })) + .sort(dynamicSort('value')); + }), + distinctUntilChanged(isEqual), + map(_ => _ as {key: string; value: string}[]) + ); + }; + private async filerValueChanged(key: string, value: T): Promise { const route = this.router.createUrlTree([this.route], { queryParams: {[key]: value}, diff --git a/src/app/modules/shows/list/list.component.html b/src/app/modules/shows/list/list.component.html index d56b6fb..ff90a11 100644 --- a/src/app/modules/shows/list/list.component.html +++ b/src/app/modules/shows/list/list.component.html @@ -9,7 +9,7 @@ { + const filterValues = params as FilterValues; + return filterValues?.owner; + }) + ); - public publicShows$ = combineLatest([this.shows$, this.lastMonths$]).pipe( - map(_ => - _[0].filter(f => { - const d = new Date(); - d.setMonth(d.getMonth() - _[1]); - return f.published && f.date.toDate() >= d; - }) + public publicShows$ = combineLatest([this.shows$, this.lastMonths$, this.owner$]).pipe( + map(([shows, lastMonths, owner]) => + shows + .filter(f => { + const d = new Date(); + d.setMonth(d.getMonth() - lastMonths); + return f.published && f.date.toDate() >= d; + }) + .filter(show => !owner || show.owner === owner) ) ); - public constructor(private showService: ShowService, private activatedRoute: ActivatedRoute) {} + public constructor( + private showService: ShowService, + private activatedRoute: ActivatedRoute + ) {} public trackBy = (index: number, show: unknown) => (show as Show).id; } diff --git a/src/app/modules/shows/new/new.component.ts b/src/app/modules/shows/new/new.component.ts index a44f4a9..48bafcf 100644 --- a/src/app/modules/shows/new/new.component.ts +++ b/src/app/modules/shows/new/new.component.ts @@ -22,7 +22,11 @@ export class NewComponent implements OnInit { }); public faSave = faSave; - public constructor(private showService: ShowService, showDataService: ShowDataService, private router: Router) { + public constructor( + private showService: ShowService, + showDataService: ShowDataService, + private router: Router + ) { this.shows$ = showDataService.list$; } diff --git a/src/app/services/filter.helper.ts b/src/app/services/filter.helper.ts index 3aee406..0916a4e 100644 --- a/src/app/services/filter.helper.ts +++ b/src/app/services/filter.helper.ts @@ -13,3 +13,20 @@ export function filterSong(song: Song, filterValue: string): boolean { function normalize(input: string): string { return input?.toLowerCase().replace(/[\s?!.,']/g, ''); } + +export const onlyUnique = (value: T, index: number, array: T[]) => array.indexOf(value) === index; + +export function dynamicSort(property: string) { + let sortOrder = 1; + if (property[0] === '-') { + sortOrder = -1; + property = property.substr(1); + } + return function (a: unknown, b: unknown) { + /* next line works with strings and numbers, + * and you may want to customize it to your needs + */ + const result = a[property] < b[property] ? -1 : a[property] > b[property] ? 1 : 0; + return result * sortOrder; + }; +} diff --git a/src/app/services/user/user.service.ts b/src/app/services/user/user.service.ts index 39d84f8..708e975 100644 --- a/src/app/services/user/user.service.ts +++ b/src/app/services/user/user.service.ts @@ -14,18 +14,7 @@ export class UserService { private iUserId$ = new BehaviorSubject(null); private iUser$ = new BehaviorSubject(null); - public constructor(private afAuth: AngularFireAuth, private db: DbService, private router: Router) { - this.afAuth.authState - .pipe( - filter(auth => !!auth), - map(auth => auth?.uid ?? ''), - tap(uid => this.iUserId$.next(uid)), - switchMap(uid => this.readUser$(uid)) - ) - .subscribe(_ => this.iUser$.next(_)); - - this.db.col$('users/').subscribe(_ => this.users$.next(_)); - } + public users$ = new BehaviorSubject([]); public get userId$(): Observable { return this.iUserId$.asObservable(); @@ -37,7 +26,22 @@ export class UserService { public currentUser = async (): Promise => firstValueFrom(this.user$); - private users$ = new BehaviorSubject([]); + public constructor( + private afAuth: AngularFireAuth, + private db: DbService, + private router: Router + ) { + this.afAuth.authState + .pipe( + filter(auth => !!auth), + map(auth => auth?.uid ?? ''), + tap(uid => this.iUserId$.next(uid)), + switchMap(uid => this.readUser$(uid)) + ) + .subscribe(_ => this.iUser$.next(_)); + + this.db.col$('users/').subscribe(_ => this.users$.next(_)); + } public getUserbyId = (userId: string): Promise => firstValueFrom(this.getUserbyId$(userId)); public getUserbyId$ = (userId: string): Observable => this.users$.pipe(map(_ => _.find(f => f.id === userId) || null));