4 Copyright (c) 2017 (null) McNull https://github.com/McNull
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 import { Component, Injector, OnDestroy } from '@angular/core';
26 import { Title } from '@angular/platform-browser';
27 import { ActivatedRouteSnapshot, NavigationEnd, NavigationStart, Router } from '@angular/router';
29 import { concat, from, Observable, of, Subscription } from 'rxjs';
30 import { distinct, filter, first, mergeMap, toArray } from 'rxjs/operators';
32 import { BreadcrumbsResolver, IBreadcrumb } from '~/app/shared/models/breadcrumbs';
35 selector: 'cd-breadcrumbs',
36 templateUrl: './breadcrumbs.component.html',
37 styleUrls: ['./breadcrumbs.component.scss']
39 export class BreadcrumbsComponent implements OnDestroy {
40 crumbs: IBreadcrumb[] = [];
42 * Useful for e2e tests.
43 * This allow us to mark the breadcrumb as pending during the navigation from
44 * one page to another.
45 * This resolves the problem of validating the breadcrumb of a new page and
46 * still get the value from the previous
49 subscription: Subscription;
50 private defaultResolver = new BreadcrumbsResolver();
52 constructor(private router: Router, private injector: Injector, private titleService: Title) {
53 this.subscription = this.router.events
54 .pipe(filter((x) => x instanceof NavigationStart))
56 this.finished = false;
59 this.subscription = this.router.events
60 .pipe(filter((x) => x instanceof NavigationEnd))
62 const currentRoot = router.routerState.snapshot.root;
64 this._resolveCrumbs(currentRoot)
67 distinct((x) => x.text),
70 const y = this.postProcess(x);
71 return this.wrapIntoObservable<IBreadcrumb[]>(y).pipe(first());
77 const title = this.getTitleFromCrumbs(this.crumbs);
78 this.titleService.setTitle(title);
84 this.subscription.unsubscribe();
87 private _resolveCrumbs(route: ActivatedRouteSnapshot): Observable<IBreadcrumb[]> {
88 let crumbs$: Observable<IBreadcrumb[]>;
90 const data = route.routeConfig && route.routeConfig.data;
92 if (data && data.breadcrumbs) {
93 let resolver: BreadcrumbsResolver;
95 if (data.breadcrumbs.prototype instanceof BreadcrumbsResolver) {
96 resolver = this.injector.get<BreadcrumbsResolver>(data.breadcrumbs);
98 resolver = this.defaultResolver;
101 const result = resolver.resolve(route);
102 crumbs$ = this.wrapIntoObservable<IBreadcrumb[]>(result).pipe(first());
107 if (route.firstChild) {
108 crumbs$ = concat<IBreadcrumb[]>(crumbs$, this._resolveCrumbs(route.firstChild));
114 postProcess(breadcrumbs: IBreadcrumb[]) {
115 const result: IBreadcrumb[] = [];
116 breadcrumbs.forEach((element) => {
117 const split = element.text.split('/');
118 if (split.length > 1) {
119 element.text = split[split.length - 1];
120 for (let i = 0; i < split.length - 1; i++) {
121 result.push({ text: split[i], path: null });
124 result.push(element);
129 isPromise(value: any): boolean {
130 return value && typeof value.then === 'function';
133 wrapIntoObservable<T>(value: T | Promise<T> | Observable<T>): Observable<T> {
134 if (value instanceof Observable) {
138 if (this.isPromise(value)) {
139 return from(Promise.resolve(value));
142 return of(value as T);
145 private getTitleFromCrumbs(crumbs: IBreadcrumb[]): string {
146 const currentLocation = crumbs
147 .map((crumb: IBreadcrumb) => {
148 return crumb.text || '';
151 if (currentLocation.length > 0) {
152 return `Ceph: ${currentLocation}`;