From 4ea264dd7f73d3b6c96eda942dde38d766d8d029 Mon Sep 17 00:00:00 2001 From: lotte Date: Thu, 20 Feb 2020 16:07:20 +0100 Subject: [PATCH] dso + i18n breadcrumbs with providers + resolvers --- .../breadcrumb/breadcrumb-config.model.ts | 7 ++++ src/app/breadcrumbs/breadcrumbs.component.ts | 36 ++++++++++++------- .../core/breadcrumbs/breadcrumbs.service.ts | 6 ++++ .../breadcrumbs/dso-breadcrumb.resolver.ts | 26 ++++++++++++++ .../breadcrumbs/dso-breadcrumbs.service.ts | 9 +++++ .../breadcrumbs/i18n-breadcrumb.resolver.ts | 29 +++++++++++++++ .../breadcrumbs/i18n-breadcrumbs.service.ts | 11 ++++++ 7 files changed, 111 insertions(+), 13 deletions(-) create mode 100644 src/app/breadcrumbs/breadcrumb/breadcrumb-config.model.ts create mode 100644 src/app/core/breadcrumbs/breadcrumbs.service.ts create mode 100644 src/app/core/breadcrumbs/dso-breadcrumb.resolver.ts create mode 100644 src/app/core/breadcrumbs/dso-breadcrumbs.service.ts create mode 100644 src/app/core/breadcrumbs/i18n-breadcrumb.resolver.ts create mode 100644 src/app/core/breadcrumbs/i18n-breadcrumbs.service.ts diff --git a/src/app/breadcrumbs/breadcrumb/breadcrumb-config.model.ts b/src/app/breadcrumbs/breadcrumb/breadcrumb-config.model.ts new file mode 100644 index 0000000000..cb43415d70 --- /dev/null +++ b/src/app/breadcrumbs/breadcrumb/breadcrumb-config.model.ts @@ -0,0 +1,7 @@ +import { BreadcrumbsService } from '../../core/breadcrumbs/breadcrumbs.service'; + +export interface BreadcrumbConfig { + provider: BreadcrumbsService; + key: string; + url?: string; +} diff --git a/src/app/breadcrumbs/breadcrumbs.component.ts b/src/app/breadcrumbs/breadcrumbs.component.ts index 5fd0f93787..c8ee9f5a1b 100644 --- a/src/app/breadcrumbs/breadcrumbs.component.ts +++ b/src/app/breadcrumbs/breadcrumbs.component.ts @@ -2,8 +2,9 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { Breadcrumb } from './breadcrumb/breadcrumb.model'; import { hasValue, isNotUndefined } from '../shared/empty.util'; -import { filter, map } from 'rxjs/operators'; -import { Subscription } from 'rxjs'; +import { filter, map, switchMap, tap } from 'rxjs/operators'; +import { combineLatest, Observable, Subscription } from 'rxjs'; +import { BreadcrumbConfig } from './breadcrumb/breadcrumb-config.model'; @Component({ selector: 'ds-breadcrumbs', @@ -11,8 +12,8 @@ import { Subscription } from 'rxjs'; styleUrls: ['./breadcrumbs.component.scss'] }) export class BreadcrumbsComponent implements OnDestroy { - breadcrumbs; - showBreadcrumbs; + breadcrumbs: Breadcrumb[]; + showBreadcrumbs: boolean; subscription: Subscription; constructor( @@ -20,23 +21,32 @@ export class BreadcrumbsComponent implements OnDestroy { private router: Router ) { this.subscription = this.router.events.pipe( - filter((e): e is NavigationEnd => e instanceof NavigationEnd) - ).subscribe(() => { - this.reset(); - this.resolveBreadcrumb(this.route.root); + filter((e): e is NavigationEnd => e instanceof NavigationEnd), + tap(() => this.reset()), + switchMap(() => this.resolveBreadcrumb(this.route.root)) + ).subscribe((breadcrumbs) => { + this.breadcrumbs = breadcrumbs; } ) } - resolveBreadcrumb(route: ActivatedRoute) { + resolveBreadcrumb(route: ActivatedRoute): Observable { const data = route.snapshot.data; 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) { - this.resolveBreadcrumb(route.firstChild); - } else if (isNotUndefined(data.showBreadcrumbs)) { - this.showBreadcrumbs = data.showBreadcrumbs; + + return this.resolveBreadcrumb(route.firstChild) } } diff --git a/src/app/core/breadcrumbs/breadcrumbs.service.ts b/src/app/core/breadcrumbs/breadcrumbs.service.ts new file mode 100644 index 0000000000..8ad2ed0334 --- /dev/null +++ b/src/app/core/breadcrumbs/breadcrumbs.service.ts @@ -0,0 +1,6 @@ +import { Breadcrumb } from '../../breadcrumbs/breadcrumb/breadcrumb.model'; +import { Observable } from 'rxjs'; + +export interface BreadcrumbsService { + getBreadcrumbs(key: string, url: string): Observable; +} diff --git a/src/app/core/breadcrumbs/dso-breadcrumb.resolver.ts b/src/app/core/breadcrumbs/dso-breadcrumb.resolver.ts new file mode 100644 index 0000000000..4d8afcf1cc --- /dev/null +++ b/src/app/core/breadcrumbs/dso-breadcrumb.resolver.ts @@ -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 { + 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 }; + } +} diff --git a/src/app/core/breadcrumbs/dso-breadcrumbs.service.ts b/src/app/core/breadcrumbs/dso-breadcrumbs.service.ts new file mode 100644 index 0000000000..452c6c5678 --- /dev/null +++ b/src/app/core/breadcrumbs/dso-breadcrumbs.service.ts @@ -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 { + return undefined; + } +} diff --git a/src/app/core/breadcrumbs/i18n-breadcrumb.resolver.ts b/src/app/core/breadcrumbs/i18n-breadcrumb.resolver.ts new file mode 100644 index 0000000000..6b5d344bc6 --- /dev/null +++ b/src/app/core/breadcrumbs/i18n-breadcrumb.resolver.ts @@ -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 { + 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 }; + } +} diff --git a/src/app/core/breadcrumbs/i18n-breadcrumbs.service.ts b/src/app/core/breadcrumbs/i18n-breadcrumbs.service.ts new file mode 100644 index 0000000000..8aefa04802 --- /dev/null +++ b/src/app/core/breadcrumbs/i18n-breadcrumbs.service.ts @@ -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 { + return observableOf([new Breadcrumb(BREADCRUMB_MESSAGE_PREFIX + key, url)]); + } +}