import {Component,Input, Output, EventEmitter, OnInit} from '@angular/core'; import {MenuItem} from 'mirra-ui/api'; import { Router, ActivatedRoute, NavigationEnd } from '@angular/router'; import { filter, distinctUntilChanged } from "rxjs/operators"; import { isNullOrUndefined } from 'util'; import { BreadcrumbService } from './breadcrumb.service'; @Component({ selector: "p-breadcrumb", templateUrl: "./breadcrumb.component.html", // changeDetection: ChangeDetectionStrategy.OnPush, // encapsulation: ViewEncapsulation.None, styleUrls: ["./breadcrumb.scss"], }) export class BreadcrumbComponent implements OnInit { static readonly ROUTE_DATA_BREADCRUMB = "breadcrumb"; // @Input() model: MenuItem[]; model: MenuItem[]; @Input() style: any; @Input() styleClass: string; @Input() home: MenuItem; @Input() symbol: any; @Output() onItemClick: EventEmitter = new EventEmitter(); constructor( private router: Router, private activatedRoute: ActivatedRoute, private breadcrumbService: BreadcrumbService ) { this.model = this.buildBreadCrumb(this.activatedRoute.root); // console.log("this.model ctor", this.model); } itemClick(event, item: MenuItem) { if (item.disabled) { event.preventDefault(); return; } if (!item.externalUrl) { event.preventDefault(); }else{ return true; } if (!item.url) { event.preventDefault(); } if (item.command) { item.command({ originalEvent: event, item: item, }); } this.onItemClick.emit({ originalEvent: event, item: item, }); } onHomeClick(event) { if (this.home) { this.itemClick(event, this.home); } } ngOnInit(): void { this.router.events .pipe( filter((event) => event instanceof NavigationEnd), distinctUntilChanged() ) .subscribe(() => { this.model = this.buildBreadCrumb(this.activatedRoute.root); // console.log("this.model init", this.model); }); // this.router.events // .pipe(filter((event) => event instanceof NavigationEnd)) // .subscribe(() =>{ // console.log("this.activatedRoute.root", this.activatedRoute.root); // this.model = this.createBreadcrumbs(this.activatedRoute.root); // }); // this.router.events // .pipe(filter((event) => event instanceof NavigationEnd)) // .pipe(map(() => this.activatedRoute)) // .pipe( // map((route) => { // while (route.firstChild) { // route = route.firstChild; // } // return route; // }) // ) // .pipe(filter((route) => route.outlet === PRIMARY_OUTLET)) // .subscribe((route) => { // console.log("route.snapshot.params", route.snapshot.params); // console.log("route", route); // // this.params = route.snapshot.params; // // this.updateData(route, null); // }); } /** * Recursively build breadcrumb according to activated route. * @param route * @param url * @param breadcrumbs */ buildBreadCrumb( route: ActivatedRoute, url: string = "", breadcrumbs: MenuItem[] = [] ): MenuItem[] { //If no routeConfig is avalailable we are on the root path let label = route.routeConfig && route.routeConfig.data ? route.routeConfig.data.breadcrumb : ""; let externalUrl = route.routeConfig && route.routeConfig.data ? route.routeConfig.data.externalUrl : ""; let externalUrl_Target = route.routeConfig && route.routeConfig.data ? route.routeConfig.data.target : ""; let isClickable = route.routeConfig && route.routeConfig.data && route.routeConfig.data.isClickable; let path = route.routeConfig && route.routeConfig.data ? route.routeConfig.path : ""; let inlinePath = route.routeConfig && route.routeConfig.data ? route.routeConfig.data.inlinePath : ""; // If the route is dynamic route such as ':id', remove it const lastRoutePart = path.split("/").pop(); const isDynamicRoute = lastRoutePart.startsWith(":"); if (isDynamicRoute && !!route.snapshot) { const paramName = lastRoutePart.split(":")[1]; path = path.replace(lastRoutePart, route.snapshot.params[paramName]); label = route.snapshot.params[paramName]; } //In the routeConfig the complete path is not available, //so we rebuild it each time let nextUrl = path ? `${url}/${path}` : url; if(!nextUrl && inlinePath){ nextUrl = inlinePath; } const breadcrumb: MenuItem = { label: label, url: nextUrl, routerLink: nextUrl, externalUrl: externalUrl ? externalUrl : "", target: (externalUrl && externalUrl_Target) ? externalUrl_Target : "", }; // Only adding route with non-empty label const newBreadcrumbs = breadcrumb.label ? [...breadcrumbs, breadcrumb] : [...breadcrumbs]; if (route.firstChild) { //If we are not on our current path yet, //there will be more children to look after, to build our breadcumb return this.buildBreadCrumb(route.firstChild, nextUrl, newBreadcrumbs); } // console.log("newBreadcrumbs", newBreadcrumbs); return newBreadcrumbs; } private createBreadcrumbs( route: ActivatedRoute, url: string = "#", breadcrumbs: MenuItem[] = [] ): MenuItem[] { const children: ActivatedRoute[] = route.children; if (children.length === 0) { return breadcrumbs; } for (const child of children) { const routeURL: string = child.snapshot.url .map((segment) => segment.path) .join("/"); if (routeURL !== "") { url += `/${routeURL}`; } const label = child.snapshot.data[BreadcrumbComponent.ROUTE_DATA_BREADCRUMB]; if (!isNullOrUndefined(label)) { breadcrumbs.push({ label, url }); } return this.createBreadcrumbs(child, url, breadcrumbs); } } trackItem(index: number, item: any) { return item.trackId; } }