dso + i18n breadcrumbs with providers + resolvers

This commit is contained in:
lotte
2020-02-20 16:07:20 +01:00
committed by Art Lowel
parent 413f798f71
commit 4ea264dd7f
7 changed files with 111 additions and 13 deletions

View File

@@ -0,0 +1,7 @@
import { BreadcrumbsService } from '../../core/breadcrumbs/breadcrumbs.service';
export interface BreadcrumbConfig {
provider: BreadcrumbsService;
key: string;
url?: string;
}

View File

@@ -2,8 +2,9 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { Breadcrumb } from './breadcrumb/breadcrumb.model'; import { Breadcrumb } from './breadcrumb/breadcrumb.model';
import { hasValue, isNotUndefined } from '../shared/empty.util'; import { hasValue, isNotUndefined } from '../shared/empty.util';
import { filter, map } from 'rxjs/operators'; import { filter, map, switchMap, tap } from 'rxjs/operators';
import { Subscription } from 'rxjs'; import { combineLatest, Observable, Subscription } from 'rxjs';
import { BreadcrumbConfig } from './breadcrumb/breadcrumb-config.model';
@Component({ @Component({
selector: 'ds-breadcrumbs', selector: 'ds-breadcrumbs',
@@ -11,8 +12,8 @@ import { Subscription } from 'rxjs';
styleUrls: ['./breadcrumbs.component.scss'] styleUrls: ['./breadcrumbs.component.scss']
}) })
export class BreadcrumbsComponent implements OnDestroy { export class BreadcrumbsComponent implements OnDestroy {
breadcrumbs; breadcrumbs: Breadcrumb[];
showBreadcrumbs; showBreadcrumbs: boolean;
subscription: Subscription; subscription: Subscription;
constructor( constructor(
@@ -20,23 +21,32 @@ export class BreadcrumbsComponent implements OnDestroy {
private router: Router private router: Router
) { ) {
this.subscription = this.router.events.pipe( this.subscription = this.router.events.pipe(
filter((e): e is NavigationEnd => e instanceof NavigationEnd) filter((e): e is NavigationEnd => e instanceof NavigationEnd),
).subscribe(() => { tap(() => this.reset()),
this.reset(); switchMap(() => this.resolveBreadcrumb(this.route.root))
this.resolveBreadcrumb(this.route.root); ).subscribe((breadcrumbs) => {
this.breadcrumbs = breadcrumbs;
} }
) )
} }
resolveBreadcrumb(route: ActivatedRoute) { resolveBreadcrumb(route: ActivatedRoute): Observable<Breadcrumb[]> {
const data = route.snapshot.data; const data = route.snapshot.data;
if (hasValue(data) && hasValue(data.breadcrumb)) { if (hasValue(data) && hasValue(data.breadcrumb)) {
this.breadcrumbs.push(data.breadcrumb); const { provider, key, url }: BreadcrumbConfig = data.breadcrumb;
if (route.children.length > 0) {
return combineLatest(provider.getBreadcrumbs(key, url), this.resolveBreadcrumb(route.firstChild))
.pipe(map((crumbs) => [].concat.apply([], crumbs)));
} else {
if (isNotUndefined(data.showBreadcrumbs)) {
this.showBreadcrumbs = data.showBreadcrumbs;
}
return provider.getBreadcrumbs(key, url);
}
} }
if (route.children.length > 0) { if (route.children.length > 0) {
this.resolveBreadcrumb(route.firstChild);
} else if (isNotUndefined(data.showBreadcrumbs)) { return this.resolveBreadcrumb(route.firstChild)
this.showBreadcrumbs = data.showBreadcrumbs;
} }
} }

View File

@@ -0,0 +1,6 @@
import { Breadcrumb } from '../../breadcrumbs/breadcrumb/breadcrumb.model';
import { Observable } from 'rxjs';
export interface BreadcrumbsService {
getBreadcrumbs(key: string, url: string): Observable<Breadcrumb[]>;
}

View File

@@ -0,0 +1,26 @@
import { BreadcrumbConfig } from '../../breadcrumbs/breadcrumb/breadcrumb-config.model';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { DSOBreadcrumbsService } from './dso-breadcrumbs.service';
/**
* The class that resolve the BreadcrumbConfig object for a route
*/
@Injectable()
export class DSOBreadcrumbResolver implements Resolve<BreadcrumbConfig> {
constructor(private breadcrumbService: DSOBreadcrumbsService) {
}
/**
* Method for resolving a site object
* @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot
* @param {RouterStateSnapshot} state The current RouterStateSnapshot
* @returns BreadcrumbConfig object
*/
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): BreadcrumbConfig {
const uuid = route.params.id;
const fullPath = route.url.join('');
const url = fullPath.substr(0, fullPath.indexOf(uuid)) + uuid;
return { provider: this.breadcrumbService, key: uuid, url: url };
}
}

View File

@@ -0,0 +1,9 @@
import { Breadcrumb } from '../../breadcrumbs/breadcrumb/breadcrumb.model';
import { BreadcrumbsService } from './breadcrumbs.service';
import { Observable } from 'rxjs';
export class DSOBreadcrumbsService implements BreadcrumbsService {
getBreadcrumbs(key: string, url: string): Observable<Breadcrumb[]> {
return undefined;
}
}

View File

@@ -0,0 +1,29 @@
import { BreadcrumbConfig } from '../../breadcrumbs/breadcrumb/breadcrumb-config.model';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
import { I18nBreadcrumbsService } from './i18n-breadcrumbs.service';
import { hasNoValue } from '../../shared/empty.util';
/**
* The class that resolve the BreadcrumbConfig object for a route
*/
@Injectable()
export class I18nBreadcrumbResolver implements Resolve<BreadcrumbConfig> {
constructor(private breadcrumbService: I18nBreadcrumbsService) {
}
/**
* Method for resolving a site object
* @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot
* @param {RouterStateSnapshot} state The current RouterStateSnapshot
* @returns BreadcrumbConfig object
*/
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): BreadcrumbConfig {
const key = route.data.breadcrumbKey;
if (hasNoValue(key)) {
throw new Error('You provided an i18nBreadcrumbResolver for url \"' + route.url + '\" but no breadcrumbKey in the route\'s data')
}
const fullPath = route.url.join('');
return { provider: this.breadcrumbService, key: key, url: fullPath };
}
}

View File

@@ -0,0 +1,11 @@
import { Breadcrumb } from '../../breadcrumbs/breadcrumb/breadcrumb.model';
import { BreadcrumbsService } from './breadcrumbs.service';
import { Observable, of as observableOf } from 'rxjs';
export const BREADCRUMB_MESSAGE_PREFIX = 'breadcrumbs.';
export class I18nBreadcrumbsService implements BreadcrumbsService {
getBreadcrumbs(key: string, url: string): Observable<Breadcrumb[]> {
return observableOf([new Breadcrumb(BREADCRUMB_MESSAGE_PREFIX + key, url)]);
}
}