better show filters
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
export interface FilterValues {
|
export interface FilterValues {
|
||||||
time: number;
|
time: number;
|
||||||
|
owner: string;
|
||||||
|
showType: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,34 @@
|
|||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Ersteller</mat-label>
|
||||||
|
<mat-select formControlName="owner">
|
||||||
|
<mat-option *ngFor="let owner of owners" [value]="owner.key">{{
|
||||||
|
owner.value
|
||||||
|
}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field appearance="outline">
|
||||||
|
<mat-label>Art der Veranstaltung</mat-label>
|
||||||
|
<mat-select formControlName="showType">
|
||||||
|
<mat-optgroup label="öffentlich">
|
||||||
|
<mat-option *ngFor="let key of showTypePublic" [value]="key">{{
|
||||||
|
key | showType
|
||||||
|
}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-optgroup>
|
||||||
|
<mat-optgroup label="privat">
|
||||||
|
<mat-option *ngFor="let key of showTypePrivate" [value]="key">{{
|
||||||
|
key | showType
|
||||||
|
}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-optgroup>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<i>Anzahl der Suchergebnisse: {{ shows.length }}</i>
|
<i>Anzahl der Suchergebnisse: {{ shows.length }}</i>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
.third {
|
.third {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
column-gap: 20px;
|
column-gap: 20px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ import {ActivatedRoute, Router} from '@angular/router';
|
|||||||
import {UntypedFormBuilder, UntypedFormGroup} from '@angular/forms';
|
import {UntypedFormBuilder, UntypedFormGroup} from '@angular/forms';
|
||||||
import {FilterValues} from './filter-values';
|
import {FilterValues} from './filter-values';
|
||||||
import {Show} from '../../services/show';
|
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({
|
@Component({
|
||||||
selector: 'app-filter',
|
selector: 'app-filter',
|
||||||
@@ -14,6 +20,9 @@ export class FilterComponent {
|
|||||||
@Input() public route = '/shows/';
|
@Input() public route = '/shows/';
|
||||||
@Input() public shows: Show[] = [];
|
@Input() public shows: Show[] = [];
|
||||||
|
|
||||||
|
public showTypePublic = ShowService.SHOW_TYPE_PUBLIC;
|
||||||
|
public showTypePrivate = ShowService.SHOW_TYPE_PRIVATE;
|
||||||
|
|
||||||
public filterFormGroup: UntypedFormGroup;
|
public filterFormGroup: UntypedFormGroup;
|
||||||
public times: KeyValue<number, string>[] = [
|
public times: KeyValue<number, string>[] = [
|
||||||
{key: 1, value: 'letzter Monat'},
|
{key: 1, value: 'letzter Monat'},
|
||||||
@@ -22,9 +31,19 @@ export class FilterComponent {
|
|||||||
{key: 99999, value: 'alle'},
|
{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({
|
this.filterFormGroup = fb.group({
|
||||||
time: 1,
|
time: 1,
|
||||||
|
owner: null,
|
||||||
|
showType: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
activatedRoute.queryParams.subscribe(params => {
|
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.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<T>(key: string, value: T): Promise<void> {
|
private async filerValueChanged<T>(key: string, value: T): Promise<void> {
|
||||||
const route = this.router.createUrlTree([this.route], {
|
const route = this.router.createUrlTree([this.route], {
|
||||||
queryParams: {[key]: value},
|
queryParams: {[key]: value},
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<app-card
|
<app-card
|
||||||
*ngIf="shows.length > 0"
|
*ngIf="shows.length > 0"
|
||||||
[padding]="false"
|
[padding]="false"
|
||||||
heading="meine Veranstaltungen"
|
heading="Meine Veranstaltungen"
|
||||||
>
|
>
|
||||||
<app-list-item
|
<app-list-item
|
||||||
*ngFor="let show of shows | sortBy: 'desc':'date'"
|
*ngFor="let show of shows | sortBy: 'desc':'date'"
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<app-card
|
<app-card
|
||||||
*ngIf="shows.length > 0"
|
*ngIf="shows.length > 0"
|
||||||
[padding]="false"
|
[padding]="false"
|
||||||
heading="veröffentlichte Veranstaltungen"
|
heading="Veröffentlichte Veranstaltungen"
|
||||||
>
|
>
|
||||||
<app-list-item
|
<app-list-item
|
||||||
*ngFor="let show of shows | sortBy: 'desc':'date'; trackBy: trackBy"
|
*ngFor="let show of shows | sortBy: 'desc':'date'; trackBy: trackBy"
|
||||||
|
|||||||
@@ -23,18 +23,29 @@ export class ListComponent {
|
|||||||
return +filterValues.time;
|
return +filterValues.time;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
public owner$ = this.activatedRoute.queryParams.pipe(
|
||||||
|
map(params => {
|
||||||
|
const filterValues = params as FilterValues;
|
||||||
|
return filterValues?.owner;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
public publicShows$ = combineLatest([this.shows$, this.lastMonths$]).pipe(
|
public publicShows$ = combineLatest([this.shows$, this.lastMonths$, this.owner$]).pipe(
|
||||||
map(_ =>
|
map(([shows, lastMonths, owner]) =>
|
||||||
_[0].filter(f => {
|
shows
|
||||||
|
.filter(f => {
|
||||||
const d = new Date();
|
const d = new Date();
|
||||||
d.setMonth(d.getMonth() - _[1]);
|
d.setMonth(d.getMonth() - lastMonths);
|
||||||
return f.published && f.date.toDate() >= d;
|
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;
|
public trackBy = (index: number, show: unknown) => (show as Show).id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,11 @@ export class NewComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
public faSave = faSave;
|
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$;
|
this.shows$ = showDataService.list$;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,3 +13,20 @@ export function filterSong(song: Song, filterValue: string): boolean {
|
|||||||
function normalize(input: string): string {
|
function normalize(input: string): string {
|
||||||
return input?.toLowerCase().replace(/[\s?!.,']/g, '');
|
return input?.toLowerCase().replace(/[\s?!.,']/g, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const onlyUnique = <T>(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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,18 +14,7 @@ export class UserService {
|
|||||||
private iUserId$ = new BehaviorSubject<string | null>(null);
|
private iUserId$ = new BehaviorSubject<string | null>(null);
|
||||||
private iUser$ = new BehaviorSubject<User | null>(null);
|
private iUser$ = new BehaviorSubject<User | null>(null);
|
||||||
|
|
||||||
public constructor(private afAuth: AngularFireAuth, private db: DbService, private router: Router) {
|
public users$ = new BehaviorSubject<User[]>([]);
|
||||||
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$<User>('users/').subscribe(_ => this.users$.next(_));
|
|
||||||
}
|
|
||||||
|
|
||||||
public get userId$(): Observable<string | null> {
|
public get userId$(): Observable<string | null> {
|
||||||
return this.iUserId$.asObservable();
|
return this.iUserId$.asObservable();
|
||||||
@@ -37,7 +26,22 @@ export class UserService {
|
|||||||
|
|
||||||
public currentUser = async (): Promise<User | null> => firstValueFrom(this.user$);
|
public currentUser = async (): Promise<User | null> => firstValueFrom(this.user$);
|
||||||
|
|
||||||
private users$ = new BehaviorSubject<User[]>([]);
|
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$<User>('users/').subscribe(_ => this.users$.next(_));
|
||||||
|
}
|
||||||
public getUserbyId = (userId: string): Promise<User | null> => firstValueFrom(this.getUserbyId$(userId));
|
public getUserbyId = (userId: string): Promise<User | null> => firstValueFrom(this.getUserbyId$(userId));
|
||||||
public getUserbyId$ = (userId: string): Observable<User | null> => this.users$.pipe(map(_ => _.find(f => f.id === userId) || null));
|
public getUserbyId$ = (userId: string): Observable<User | null> => this.users$.pipe(map(_ => _.find(f => f.id === userId) || null));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user