diff --git a/README.md b/README.md index 2ce50f0..485286c 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ - ✅ **Disable breadcrumb**: Disable specific routes so that navigation is disbaled to intermediate routes. -- ✅ **Customization**: Customize breadcrumb template to show **icons as label prefix**, **use pipes on text**, **add i18n**, etc. +- ✅ **Customization**: Customize breadcrumb template to show **icons as label prefix**, **use pipes on text**, **add i18n with ngx-translate**, etc. - ✅ **Styling**: **Separator** and **Styles** can be customized with ease. diff --git a/apps/simple-demo-e2e/src/integration/app.spec.ts b/apps/simple-demo-e2e/src/integration/app.spec.ts index c60bd52..489faf3 100644 --- a/apps/simple-demo-e2e/src/integration/app.spec.ts +++ b/apps/simple-demo-e2e/src/integration/app.spec.ts @@ -1,7 +1,11 @@ describe('simple-demo', () => { it('should contain breadcrumbs for books', () => { cy.visit('/'); + // initially within ngIf and not shown + cy.get('xng-breadcrumb').should('not.exist'); + cy.get('button').contains('Toggle Breadcrumb Visibility').click(); cy.get('xng-breadcrumb').contains('Dashboard'); + // shouldn't have default seperator if Home breadcrumb is not defined cy.get('.xng-breadcrumb-list').contains('/').should('not.exist'); cy.get('a').contains('Order Details').click(); diff --git a/apps/simple-demo/src/app/app.component.html b/apps/simple-demo/src/app/app.component.html index 8453ad4..cd08879 100644 --- a/apps/simple-demo/src/app/app.component.html +++ b/apps/simple-demo/src/app/app.component.html @@ -1,35 +1,12 @@

xng-breadcrumb

Angular version {{ name }}

- +
+ +
- + + + diff --git a/apps/simple-demo/src/app/app.component.ts b/apps/simple-demo/src/app/app.component.ts index 0a7e4db..87c949c 100644 --- a/apps/simple-demo/src/app/app.component.ts +++ b/apps/simple-demo/src/app/app.component.ts @@ -7,8 +7,15 @@ import { Router } from '@angular/router'; styleUrls: ['./app.component.css'], }) export class AppComponent { + showBreadcrumbs = false; + constructor(router: Router) { router.routeReuseStrategy.shouldReuseRoute = () => false; } + + toggleBreadcrumbVisibility() { + this.showBreadcrumbs = !this.showBreadcrumbs; + } + name = 'Angular ' + VERSION.major; } diff --git a/apps/simple-demo/src/app/app.module.ts b/apps/simple-demo/src/app/app.module.ts index 38047a3..d44ca37 100644 --- a/apps/simple-demo/src/app/app.module.ts +++ b/apps/simple-demo/src/app/app.module.ts @@ -1,16 +1,15 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; -import { BreadcrumbModule } from '@xng/xng-breadcrumb'; +import { BreadcrumbModule, BreadcrumbService } from '@xng/xng-breadcrumb'; import { AppRoutingModule } from './app.routing.module'; import { AppComponent } from './app.component'; -import { Page1Component } from './page1.component'; -import { Page2Component } from './page2.component'; +import { PageComponent } from './page.component'; @NgModule({ - declarations: [AppComponent, Page1Component, Page2Component], + declarations: [AppComponent, PageComponent], imports: [BrowserModule, BreadcrumbModule, AppRoutingModule], - providers: [], + providers: [BreadcrumbService], bootstrap: [AppComponent], }) export class AppModule {} diff --git a/apps/simple-demo/src/app/app.routing.module.ts b/apps/simple-demo/src/app/app.routing.module.ts index b9844c7..894f301 100644 --- a/apps/simple-demo/src/app/app.routing.module.ts +++ b/apps/simple-demo/src/app/app.routing.module.ts @@ -1,6 +1,7 @@ +import { AppComponent } from './app.component'; +import { PageComponent } from './page.component'; import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; -import { AppComponent } from './app.component'; export const appRoutes: Routes = [ { @@ -10,7 +11,7 @@ export const appRoutes: Routes = [ }, { path: 'homepage', - component: AppComponent, + component: PageComponent, data: { breadcrumb: 'Dashboard', }, @@ -19,35 +20,35 @@ export const appRoutes: Routes = [ path: 'company', data: { breadcrumb: 'Companies' }, children: [ - { path: '', component: AppComponent }, + { path: '', component: PageComponent }, { path: ':companyId', data: { breadcrumb: 'Company Name' }, children: [ - { path: '', component: AppComponent }, + { path: '', component: PageComponent }, { path: 'order', data: { breadcrumb: 'Orders' }, children: [ - { path: '', component: AppComponent }, + { path: '', component: PageComponent }, { path: ':orderId', data: { breadcrumb: 'Order Details' }, children: [ - { path: '', component: AppComponent }, + { path: '', component: PageComponent }, { path: 'items', - component: AppComponent, + component: PageComponent, data: { breadcrumb: 'Items' }, }, { path: 'payment', - component: AppComponent, + component: PageComponent, data: { breadcrumb: 'Payment Info' }, }, { path: 'delivery', - component: AppComponent, + component: PageComponent, data: { breadcrumb: 'Delivery Details' }, }, ], diff --git a/apps/simple-demo/src/app/hello.component.ts b/apps/simple-demo/src/app/hello.component.ts deleted file mode 100644 index e0dbeac..0000000 --- a/apps/simple-demo/src/app/hello.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Component, Input } from '@angular/core'; - -@Component({ - selector: 'hello', - template: `

Hello {{ name }}!

`, - styles: [ - ` - h1 { - font-family: Lato; - } - `, - ], -}) -export class HelloComponent { - @Input() name: string; -} diff --git a/apps/simple-demo/src/app/page.component.html b/apps/simple-demo/src/app/page.component.html new file mode 100644 index 0000000..a277ffd --- /dev/null +++ b/apps/simple-demo/src/app/page.component.html @@ -0,0 +1,34 @@ + diff --git a/apps/simple-demo/src/app/page.component.ts b/apps/simple-demo/src/app/page.component.ts new file mode 100644 index 0000000..94f2209 --- /dev/null +++ b/apps/simple-demo/src/app/page.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'page', + templateUrl: './page.component.html', +}) +export class PageComponent {} diff --git a/apps/simple-demo/src/app/page1.component.ts b/apps/simple-demo/src/app/page1.component.ts deleted file mode 100644 index 9135b12..0000000 --- a/apps/simple-demo/src/app/page1.component.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'page1', - template: `

In Page 1

`, -}) -export class Page1Component {} diff --git a/apps/simple-demo/src/app/page2.component.ts b/apps/simple-demo/src/app/page2.component.ts deleted file mode 100644 index 242bc3e..0000000 --- a/apps/simple-demo/src/app/page2.component.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'page2', - template: `

In Page 2

`, -}) -export class Page2Component {} diff --git a/libs/xng-breadcrumb/src/lib/breadcrumb.component.ts b/libs/xng-breadcrumb/src/lib/breadcrumb.component.ts index 6c00ad6..768bd15 100644 --- a/libs/xng-breadcrumb/src/lib/breadcrumb.component.ts +++ b/libs/xng-breadcrumb/src/lib/breadcrumb.component.ts @@ -6,7 +6,7 @@ import { TemplateRef, ViewEncapsulation, } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { Observable, Subscription } from 'rxjs'; import { map } from 'rxjs/operators'; import { BreadcrumbItemDirective } from './breadcrumb-item.directive'; diff --git a/libs/xng-breadcrumb/src/lib/breadcrumb.service.ts b/libs/xng-breadcrumb/src/lib/breadcrumb.service.ts index 46c9086..9ebef67 100644 --- a/libs/xng-breadcrumb/src/lib/breadcrumb.service.ts +++ b/libs/xng-breadcrumb/src/lib/breadcrumb.service.ts @@ -1,5 +1,6 @@ import { Injectable } from '@angular/core'; import { + ActivatedRoute, ActivatedRouteSnapshot, Router, RoutesRecognized, @@ -53,7 +54,7 @@ export class BreadcrumbService { private breadcrumbs = new BehaviorSubject([]); public breadcrumbs$ = this.breadcrumbs.asObservable(); - constructor(private router: Router) { + constructor(private activatedRoute: ActivatedRoute, private router: Router) { this.detectRouteChanges(); } @@ -61,22 +62,31 @@ export class BreadcrumbService { * Whenever route changes build breadcrumb list again */ private detectRouteChanges() { + // Special case where breadcrumb service & component instantiates after a route is navigated. + // Ex: put breadcrumbs within *ngIf and this.router.events would be empty + if (this.router.navigated) { + this.setupBreadcrumbs(this.activatedRoute.snapshot); + } + this.router.events .pipe(filter((event) => event instanceof RoutesRecognized)) .subscribe((event) => { // activatedRoute doesn't carry data when shouldReuseRoute returns false // use the event data with RoutesRecognized as workaround if (event instanceof RoutesRecognized) { - console.log(event.state.root.firstChild.data.title); - this.previousBreadcrumbs = this.currentBreadcrumbs; - // breadcrumb label for base OR root path. Usually, this can be set as 'Home' - const rootBreadcrumb = this.getRootBreadcrumb(); - this.currentBreadcrumbs = rootBreadcrumb ? [rootBreadcrumb] : []; - this.prepareBreadcrumbList(event.state.root, this.baseHref); + this.setupBreadcrumbs(event.state.root); } }); } + private setupBreadcrumbs(activatedRouteSnapshot: ActivatedRouteSnapshot) { + this.previousBreadcrumbs = this.currentBreadcrumbs; + // breadcrumb label for base OR root path. Usually, this can be set as 'Home' + const rootBreadcrumb = this.getRootBreadcrumb(); + this.currentBreadcrumbs = rootBreadcrumb ? [rootBreadcrumb] : []; + this.prepareBreadcrumbList(activatedRouteSnapshot, this.baseHref); + } + private getRootBreadcrumb() { const rootConfig = this.router.config.find((config) => config.path === ''); const rootBreadcrumb = this.extractObject(rootConfig?.data?.breadcrumb);