From 14eb1890daeab3e8c931ad5d0499420189ea1dd6 Mon Sep 17 00:00:00 2001 From: Sarthak0702 Date: Wed, 19 Jan 2022 02:09:27 +0530 Subject: [PATCH] mgr/dashboard: Page title should indicate current location Added titleService to BreadcrumbsComponent. Fixes: https://tracker.ceph.com/issues/36587 Signed-off-by: Sarthak0702 --- .../breadcrumbs/breadcrumbs.component.spec.ts | 40 +++++++++++++++++++ .../breadcrumbs/breadcrumbs.component.ts | 18 ++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.spec.ts index b6551f780e9..f10c6a56d85 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.spec.ts @@ -1,6 +1,7 @@ import { CommonModule } from '@angular/common'; import { Component } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { Title } from '@angular/platform-browser'; import { Router, Routes } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; @@ -12,6 +13,7 @@ describe('BreadcrumbsComponent', () => { let component: BreadcrumbsComponent; let fixture: ComponentFixture; let router: Router; + let titleService: Title; @Component({ selector: 'cd-fake', template: '' }) class FakeComponent {} @@ -42,6 +44,11 @@ describe('BreadcrumbsComponent', () => { ] } ] + }, + { + path: 'error', + component: FakeComponent, + data: { breadcrumbs: '' } } ]; @@ -54,6 +61,7 @@ describe('BreadcrumbsComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(BreadcrumbsComponent); router = TestBed.inject(Router); + titleService = TestBed.inject(Title); component = fixture.componentInstance; fixture.detectChanges(); expect(component.crumbs).toEqual([]); @@ -128,4 +136,36 @@ describe('BreadcrumbsComponent', () => { component.ngOnDestroy(); expect(component.subscription.closed).toBeTruthy(); }); + + it('should display no breadcrumbs in page title when navigating to dashboard', fakeAsync(() => { + fixture.ngZone.run(() => { + router.navigateByUrl(''); + }); + tick(); + expect(titleService.getTitle()).toEqual('Ceph'); + })); + + it('should display no breadcrumbs in page title when a page is not found', fakeAsync(() => { + fixture.ngZone.run(() => { + router.navigateByUrl('/error'); + }); + tick(); + expect(titleService.getTitle()).toEqual('Ceph'); + })); + + it('should display 2 breadcrumbs in page title when navigating to hosts', fakeAsync(() => { + fixture.ngZone.run(() => { + router.navigateByUrl('/hosts'); + }); + tick(); + expect(titleService.getTitle()).toEqual('Ceph: Cluster > Hosts'); + })); + + it('should display 3 breadcrumbs in page title when navigating to RBD Add', fakeAsync(() => { + fixture.ngZone.run(() => { + router.navigateByUrl('/block/rbd/add'); + }); + tick(); + expect(titleService.getTitle()).toEqual('Ceph: Block > Images > Add'); + })); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.ts index d933081ab9c..860b89ec90b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/breadcrumbs/breadcrumbs.component.ts @@ -23,6 +23,7 @@ THE SOFTWARE. */ import { Component, Injector, OnDestroy } from '@angular/core'; +import { Title } from '@angular/platform-browser'; import { ActivatedRouteSnapshot, NavigationEnd, NavigationStart, Router } from '@angular/router'; import { concat, from, Observable, of, Subscription } from 'rxjs'; @@ -48,7 +49,7 @@ export class BreadcrumbsComponent implements OnDestroy { subscription: Subscription; private defaultResolver = new BreadcrumbsResolver(); - constructor(private router: Router, private injector: Injector) { + constructor(private router: Router, private injector: Injector, private titleService: Title) { this.subscription = this.router.events .pipe(filter((x) => x instanceof NavigationStart)) .subscribe(() => { @@ -73,6 +74,8 @@ export class BreadcrumbsComponent implements OnDestroy { .subscribe((x) => { this.finished = true; this.crumbs = x; + const title = this.getTitleFromCrumbs(this.crumbs); + this.titleService.setTitle(title); }); }); } @@ -138,4 +141,17 @@ export class BreadcrumbsComponent implements OnDestroy { return of(value as T); } + + private getTitleFromCrumbs(crumbs: IBreadcrumb[]): string { + const currentLocation = crumbs + .map((crumb: IBreadcrumb) => { + return crumb.text || ''; + }) + .join(' > '); + if (currentLocation.length > 0) { + return `Ceph: ${currentLocation}`; + } else { + return 'Ceph'; + } + } } -- 2.47.3