diff --git a/src/app/modules/shows/list/filter/filter.component.html b/src/app/modules/shows/list/filter/filter.component.html index 5dba75c..292dff5 100644 --- a/src/app/modules/shows/list/filter/filter.component.html +++ b/src/app/modules/shows/list/filter/filter.component.html @@ -14,6 +14,7 @@ Ersteller + Alle {{ owner.value }} @@ -24,6 +25,7 @@ Art der Veranstaltung + Alle {{ key | showType @@ -41,5 +43,5 @@ - Anzahl der Suchergebnisse: {{ shows.length }} + Anzahl der Suchergebnisse: {{ shows?.length ?? 0 }} diff --git a/src/app/modules/shows/list/filter/filter.component.ts b/src/app/modules/shows/list/filter/filter.component.ts index 4374d1c..ce735e9 100644 --- a/src/app/modules/shows/list/filter/filter.component.ts +++ b/src/app/modules/shows/list/filter/filter.component.ts @@ -54,6 +54,8 @@ export class FilterComponent { activatedRoute.queryParams.subscribe(params => { const filterValues = params as FilterValues; if (filterValues.time) this.filterFormGroup.controls.time.setValue(+filterValues.time); + this.filterFormGroup.controls.owner.setValue(filterValues.owner ?? null, {emitEvent: false}); + this.filterFormGroup.controls.showType.setValue(filterValues.showType ?? null, {emitEvent: false}); }); this.filterFormGroup.controls.time.valueChanges.subscribe(_ => void this.filerValueChanged('time', _ as number)); @@ -87,7 +89,7 @@ export class FilterComponent { private async filerValueChanged(key: string, value: T): Promise { const route = this.router.createUrlTree([this.route], { - queryParams: {[key]: value}, + queryParams: {[key]: value || null}, queryParamsHandling: 'merge', }); await this.router.navigateByUrl(route); diff --git a/src/app/modules/shows/list/list.component.ts b/src/app/modules/shows/list/list.component.ts index 1fb5f5e..dfe57c1 100644 --- a/src/app/modules/shows/list/list.component.ts +++ b/src/app/modules/shows/list/list.component.ts @@ -5,7 +5,7 @@ import {fade} from '../../../animations'; import {ShowService} from '../services/show.service'; import {FilterValues} from './filter/filter-values'; import {ActivatedRoute, RouterLink} from '@angular/router'; -import {map} from 'rxjs/operators'; +import {map, switchMap} from 'rxjs/operators'; import {RoleDirective} from '../../../services/user/role.directive'; import {ListHeaderComponent} from '../../../widget-modules/components/list-header/list-header.component'; import {AsyncPipe, NgFor, NgIf} from '@angular/common'; @@ -43,18 +43,26 @@ export class ListComponent { return filterValues?.showType; }) ); + public queriedPublicShows$ = this.lastMonths$.pipe(switchMap(lastMonths => this.showService.listPublicSince$(lastMonths))); - public publicShows$ = combineLatest([this.shows$, this.lastMonths$, this.owner$, this.showType$]).pipe( - map(([shows, lastMonths, owner, showType]) => - shows - .filter(f => { - const d = new Date(); - d.setMonth(d.getMonth() - lastMonths); - return f.published && f.date.toDate() >= d; - }) + public fallbackPublicShows$ = combineLatest([this.shows$, this.lastMonths$]).pipe( + map(([shows, lastMonths]) => { + const startDate = new Date(); + startDate.setHours(0, 0, 0, 0); + startDate.setDate(startDate.getDate() - lastMonths * 30); + + return shows.filter(show => show.published && !show.archived && show.date.toDate() >= startDate); + }) + ); + + public publicShows$ = combineLatest([this.queriedPublicShows$, this.fallbackPublicShows$, this.owner$, this.showType$]).pipe( + map(([queriedShows, fallbackShows, owner, showType]) => { + const shows = queriedShows.length > 0 || fallbackShows.length === 0 ? queriedShows : fallbackShows; + + return shows .filter(show => !owner || show.owner === owner) - .filter(show => !showType || show.showType === showType) - ) + .filter(show => !showType || show.showType === showType); + }) ); public constructor( diff --git a/src/app/modules/shows/services/show-data.service.ts b/src/app/modules/shows/services/show-data.service.ts index e3b5f21..1f16cad 100644 --- a/src/app/modules/shows/services/show-data.service.ts +++ b/src/app/modules/shows/services/show-data.service.ts @@ -3,6 +3,8 @@ import {Observable} from 'rxjs'; import {DbService} from '../../../services/db.service'; import {Show} from './show'; import {map, shareReplay} from 'rxjs/operators'; +import {QueryFn} from '@angular/fire/compat/firestore/interfaces'; +import firebase from 'firebase/compat/app'; @Injectable({ providedIn: 'root', @@ -22,6 +24,23 @@ export class ShowDataService { public listRaw$ = () => this.dbService.col$(this.collection); + public listPublicSince$(lastMonths: number): Observable { + const startDate = new Date(); + startDate.setHours(0, 0, 0, 0); + startDate.setDate(startDate.getDate() - lastMonths * 30); + const startTimestamp = firebase.firestore.Timestamp.fromDate(startDate); + + const queryFn: QueryFn = ref => ref.where('published', '==', true).where('date', '>=', startTimestamp).orderBy('date', 'desc'); + + return this.dbService.col$(this.collection, queryFn).pipe( + map(shows => shows.filter(show => !show.archived)), + shareReplay({ + bufferSize: 1, + refCount: true, + }) + ); + } + public read$ = (showId: string): Observable => this.dbService.doc$(`${this.collection}/${showId}`); public update = async (showId: string, data: Partial): Promise => await this.dbService.doc(`${this.collection}/${showId}`).update(data); diff --git a/src/app/modules/shows/services/show.service.ts b/src/app/modules/shows/services/show.service.ts index 488c94e..3f51978 100644 --- a/src/app/modules/shows/services/show.service.ts +++ b/src/app/modules/shows/services/show.service.ts @@ -23,6 +23,7 @@ export class ShowService { } public read$ = (showId: string): Observable => this.showDataService.read$(showId); + public listPublicSince$ = (lastMonths: number): Observable => this.showDataService.listPublicSince$(lastMonths); public list$(publishedOnly = false): Observable { return this.userService.user$.pipe(