pp-breadcrumbs
Version:
PP-Breadcrumbs is an Angular 10 library generating breadcrumbs based on the routing state.
132 lines (124 loc) • 5.57 kB
JavaScript
import { Injectable, ɵɵdefineInjectable, ɵɵinject, INJECTOR, Injector, Component, NgModule } from '@angular/core';
import { NavigationEnd, Router, RouterModule } from '@angular/router';
import { of, BehaviorSubject, concat, isObservable, from } from 'rxjs';
import { template } from 'lodash';
import { filter, concatMap, mergeMap, distinct, toArray, first, tap } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
class PpBreadcrumbsResolver {
resolve(route, state) {
const data = route.routeConfig.data;
const path = this.getFullPath(route);
const rawText = typeof data.breadcrumbs === 'string' ? data.breadcrumbs : data.breadcrumbs.text || data.text || path;
return of([
{
path: path,
text: this.stringFormat(rawText, route.data)
}
]);
}
getFullPath(route) {
const relativePath = (segments) => segments.reduce((a, v) => (a += '/' + v.path), '');
const fullPath = (routes) => routes.reduce((a, v) => (a += relativePath(v.url)), '');
return fullPath(route.pathFromRoot);
}
stringFormat(templateString, binding) {
const compiled = template(templateString, { interpolate: /{{(.+?)}}/g });
return compiled(binding);
}
}
PpBreadcrumbsResolver.decorators = [
{ type: Injectable }
];
class PpBreadcrumbsService {
constructor(router, injector) {
this.router = router;
this.injector = injector;
this.breadcrumbs = new BehaviorSubject([]);
this.defaultResolver = new PpBreadcrumbsResolver();
this.subscription = this.router.events.pipe(filter(x => x instanceof NavigationEnd), concatMap(() => this.onNavigationEnd())).subscribe();
this.onNavigationEnd().subscribe();
}
get crumbs$() {
return this.breadcrumbs.asObservable();
}
ngOnDestroy() {
var _a;
(_a = this.subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
this.breadcrumbs.complete();
}
onNavigationEnd() {
return this.resolveCrumbs(this.router.routerState.snapshot.root).pipe(mergeMap((breadcrumbs) => breadcrumbs), distinct((breadcrumb) => breadcrumb.text), toArray(), mergeMap((breadcrumbs) => {
return this.postProcess ? this.wrapIntoObservable(this.postProcess(breadcrumbs)).pipe(first()) : of(breadcrumbs);
}), tap((breadcrumbs) => this.breadcrumbs.next(breadcrumbs)));
}
resolveCrumbs(route) {
var _a;
let crumbs$ = of([]);
const data = (_a = route.routeConfig) === null || _a === void 0 ? void 0 : _a.data;
if (data === null || data === void 0 ? void 0 : data.breadcrumbs) {
const resolver = this.getBreadcrumbResolver(data.breadcrumbs);
const result = resolver.resolve(route, this.router.routerState.snapshot);
crumbs$ = this.wrapIntoObservable(result).pipe(first());
}
return route.firstChild ? concat(crumbs$, this.resolveCrumbs(route.firstChild)) : crumbs$;
}
getBreadcrumbResolver(breadcrumbs) {
return typeof breadcrumbs === 'function' && breadcrumbs.prototype instanceof PpBreadcrumbsResolver
? this.injector.get(breadcrumbs)
: this.defaultResolver;
}
wrapIntoObservable(value) {
return isObservable(value) ? value : from(Promise.resolve(value));
}
}
PpBreadcrumbsService.ɵprov = ɵɵdefineInjectable({ factory: function PpBreadcrumbsService_Factory() { return new PpBreadcrumbsService(ɵɵinject(Router), ɵɵinject(INJECTOR)); }, token: PpBreadcrumbsService, providedIn: "root" });
PpBreadcrumbsService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
PpBreadcrumbsService.ctorParameters = () => [
{ type: Router },
{ type: Injector }
];
class PpBreadcrumbsComponent {
constructor(service) {
this.service = service;
}
ngOnInit() {
this.subscription = this.service.crumbs$.subscribe((crumbs) => {
this.crumbs = crumbs;
});
}
ngOnDestroy() {
var _a;
(_a = this.subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
}
}
PpBreadcrumbsComponent.decorators = [
{ type: Component, args: [{
selector: 'pp-breadcrumbs',
template: "<ol *ngIf=\"crumbs.length\" class=\"breadcrumb\">\r\n <li *ngFor=\"let crumb of crumbs; let first = first; let last = last\" [ngClass]=\"{ 'active': last }\" class=\"breadcrumb-item\">\r\n <a *ngIf=\"!last; else lastBreadcrumb\" [routerLink]=\"crumb.path\" [innerHTML]=\"crumb.text\"></a>\r\n <ng-template #lastBreadcrumb>\r\n <span [innerHTML]=\"crumb.text\"></span>\r\n </ng-template>\r\n </li>\r\n</ol>\r\n",
styles: [""]
},] }
];
PpBreadcrumbsComponent.ctorParameters = () => [
{ type: PpBreadcrumbsService }
];
class PpBreadcrumbsModule {
}
PpBreadcrumbsModule.decorators = [
{ type: NgModule, args: [{
declarations: [PpBreadcrumbsComponent],
imports: [CommonModule, RouterModule],
exports: [PpBreadcrumbsComponent]
},] }
];
/*
* Public API Surface of pp-breadcrumbs
*/
/**
* Generated bundle index. Do not edit.
*/
export { PpBreadcrumbsComponent, PpBreadcrumbsModule, PpBreadcrumbsResolver, PpBreadcrumbsService };
//# sourceMappingURL=pp-breadcrumbs.js.map