the /browse endpoint now allow filters to be added from the queryParams

This commit is contained in:
Zoe Roux 2020-09-24 23:33:46 +02:00
parent c83d80ab51
commit 52797d869c
3 changed files with 69 additions and 27 deletions

View File

@ -25,12 +25,12 @@ import {WatchItem} from "../models/watch-item";
const routes: Routes = [ const routes: Routes = [
{path: "browse", component: ItemsGridComponent, pathMatch: "full", {path: "browse", component: ItemsGridComponent, pathMatch: "full",
resolve: { items: PageResolver.forResource<LibraryItem>("items") }, resolve: {items: PageResolver.forResource<LibraryItem>("items", ItemsGridComponent.routeMapper)},
canLoad: [AuthGuard.forPermissions("read")], canLoad: [AuthGuard.forPermissions("read")],
canActivate: [AuthGuard.forPermissions("read")] canActivate: [AuthGuard.forPermissions("read")]
}, },
{path: "browse/:slug", component: ItemsGridComponent, {path: "browse/:slug", component: ItemsGridComponent,
resolve: { items: PageResolver.forResource<LibraryItem>("library/:slug/items") }, resolve: {items: PageResolver.forResource<LibraryItem>("library/:slug/items", ItemsGridComponent.routeMapper)},
canLoad: [AuthGuard.forPermissions("read")], canLoad: [AuthGuard.forPermissions("read")],
canActivate: [AuthGuard.forPermissions("read")] canActivate: [AuthGuard.forPermissions("read")]
}, },

View File

@ -1,5 +1,5 @@
import { Component, Input, OnInit } from "@angular/core"; import { Component, Input, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router"; import { ActivatedRoute, ActivatedRouteSnapshot, Router } from "@angular/router";
import { DomSanitizer } from '@angular/platform-browser'; import { DomSanitizer } from '@angular/platform-browser';
import { Genre } from "../../../models/resources/genre"; import { Genre } from "../../../models/resources/genre";
import { LibraryItem } from "../../../models/resources/library-item"; import { LibraryItem } from "../../../models/resources/library-item";
@ -36,7 +36,8 @@ export class ItemsGridComponent implements OnInit
constructor(private route: ActivatedRoute, constructor(private route: ActivatedRoute,
private sanitizer: DomSanitizer, private sanitizer: DomSanitizer,
private loader: PreLoaderService, private loader: PreLoaderService,
public client: HttpClient) public client: HttpClient,
private router: Router)
{ {
this.route.data.subscribe((data) => this.route.data.subscribe((data) =>
{ {
@ -45,13 +46,29 @@ export class ItemsGridComponent implements OnInit
this.loader.load<Genre>("/api/genres?limit=0").subscribe(data => this.loader.load<Genre>("/api/genres?limit=0").subscribe(data =>
{ {
this.genres = data; this.genres = data;
let selectedGenres: string[] = [];
if (this.route.snapshot.queryParams.genres?.startsWith("ctn:"))
selectedGenres = this.route.snapshot.queryParams.genres.substr(4).split(',');
this.filters.genres = this.genres.filter(x => selectedGenres.includes(x.slug));
}); });
this.loader.load<Studio>("/api/studios?limit=0").subscribe(data => this.loader.load<Studio>("/api/studios?limit=0").subscribe(data =>
{ {
this.studios = data; this.studios = data;
this.filters.studio = this.studios.find(x => x.slug == this.route.params["studio"]);
}); });
} }
static routeMapper(route: ActivatedRouteSnapshot, endpoint: string): string
{
const filter: string[] = ["genres", "studio"];
let queryParams: [string, string][] = Object.entries(route.queryParams).filter(x => filter.includes(x[0]));
if (queryParams.length > 0)
endpoint = "shows";
let params: string = '?' + queryParams.map(x => `${x[0]}=${x[1]}`).join('&');
return `api/${endpoint}${params}`
}
ngOnInit() ngOnInit()
{ {
this.defaultType = this.page.this.match(/\/(\w*)($|\?)/)[1]; this.defaultType = this.page.this.match(/\/(\w*)($|\?)/)[1];
@ -107,12 +124,22 @@ export class ItemsGridComponent implements OnInit
: new URL(this.page.changeType(this.defaultType)); : new URL(this.page.changeType(this.defaultType));
} }
let param: string;
if (isArray && this.filters[category].length > 0) if (isArray && this.filters[category].length > 0)
url.searchParams.set(category, `ctn:${this.filters[category].map(x => x.slug).join(',')}`); param = `ctn:${this.filters[category].map(x => x.slug).join(',')}`;
else if (!isArray && this.filters[category] != null) else if (!isArray && this.filters[category] != null)
url.searchParams.set(category, filter.slug) param = filter.slug;
if (param != null)
url.searchParams.set(category, param);
else else
url.searchParams.delete(category) url.searchParams.delete(category)
this.router.navigate([], {
relativeTo: this.route,
queryParams: { [category]: param },
replaceUrl: true,
queryParamsHandling: "merge"
});
this.client.get<Page<Show>>(url.toString()) this.client.get<Page<Show>>(url.toString())
.subscribe(x => this.page = Object.assign(new Page<Show>(), x)); .subscribe(x => this.page = Object.assign(new Page<Show>(), x));
} }

View File

@ -7,12 +7,14 @@ import {catchError, map} from 'rxjs/operators';
import {Page} from "../../models/page"; import {Page} from "../../models/page";
import {IResource} from "../../models/resources/resource"; import {IResource} from "../../models/resources/resource";
type RouteMapper = (route: ActivatedRouteSnapshot, endpoint: string) => string;
@Injectable() @Injectable()
export class PageResolver export class PageResolver
{ {
public static resolvers: any[] = []; public static resolvers: any[] = [];
static forResource<T extends IResource>(resource: string) static forResource<T extends IResource>(resource: string, copyParams: boolean | string[] | RouteMapper = false)
{ {
@Injectable() @Injectable()
class Resolver implements Resolve<Page<T>> class Resolver implements Resolve<Page<T>>
@ -24,8 +26,21 @@ export class PageResolver
resolve(route: ActivatedRouteSnapshot): Page<T> | Observable<Page<T>> | Promise<Page<T>> resolve(route: ActivatedRouteSnapshot): Page<T> | Observable<Page<T>> | Promise<Page<T>>
{ {
let res: string = resource.replace(/:(.*?)(\/|$)/, (x, y) => `${route.paramMap.get(y)}/`); let res: string = resource.replace(/:(.*?)(\/|$)/, (x, y) => `${route.paramMap.get(y)}/`);
let uri: string;
if (typeof copyParams == "function")
uri = copyParams(route, res);
else
{
let queryParams: [string, string][] = copyParams == true
? Object.entries(route.queryParams)
: Object.entries(route.queryParams).filter(x => copyParams && copyParams.includes(x[0]));
let params: string = queryParams.length > 0
? '?' + queryParams.map(x => `${x[0]}=${x[1]}`).join('&')
: "";
uri = `api/${res}${params}`;
}
return this.http.get<Page<T>>(`api/${res}`) return this.http.get<Page<T>>(uri)
.pipe( .pipe(
map(x => Object.assign(new Page<T>(), x)), map(x => Object.assign(new Page<T>(), x)),
catchError((error: HttpErrorResponse) => catchError((error: HttpErrorResponse) =>