feat: add breadcrumb component (#63)
Add breadcrumb component for dynamic generation of breadcrumb links. Fixes #62
This commit is contained in:
@@ -35,8 +35,8 @@ import { AppRoutingModule } from './app-routing.module';
|
|||||||
NgxChartsModule,
|
NgxChartsModule,
|
||||||
CoreModule,
|
CoreModule,
|
||||||
SharedModule,
|
SharedModule,
|
||||||
NavigationModule,
|
|
||||||
HomeModule,
|
HomeModule,
|
||||||
|
NavigationModule,
|
||||||
AboutModule,
|
AboutModule,
|
||||||
LoginModule,
|
LoginModule,
|
||||||
ClientsModule,
|
ClientsModule,
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import { ShellComponent } from './shell/shell.component';
|
|||||||
import { SidenavComponent } from './shell/sidenav/sidenav.component';
|
import { SidenavComponent } from './shell/sidenav/sidenav.component';
|
||||||
import { ToolbarComponent } from './shell/toolbar/toolbar.component';
|
import { ToolbarComponent } from './shell/toolbar/toolbar.component';
|
||||||
import { ContentComponent } from './shell/content/content.component';
|
import { ContentComponent } from './shell/content/content.component';
|
||||||
|
import { BreadcrumbComponent } from './shell/breadcrumb/breadcrumb.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -100,7 +101,8 @@ import { ContentComponent } from './shell/content/content.component';
|
|||||||
ShellComponent,
|
ShellComponent,
|
||||||
SidenavComponent,
|
SidenavComponent,
|
||||||
ToolbarComponent,
|
ToolbarComponent,
|
||||||
ContentComponent
|
ContentComponent,
|
||||||
|
BreadcrumbComponent
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
LayoutModule,
|
LayoutModule,
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<nav>
|
||||||
|
<div class="breadcrumb-wrapper">
|
||||||
|
<ul>
|
||||||
|
<li *ngFor="let breadcrumb of breadcrumbs; let last = last">
|
||||||
|
<span *ngIf="!last">
|
||||||
|
<a *ngIf="!last" [routerLink]="breadcrumb.url">{{breadcrumb.label}}</a> >
|
||||||
|
</span>
|
||||||
|
<span *ngIf="last">{{ breadcrumb.label }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
li {
|
||||||
|
display: inline;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { BreadcrumbComponent } from './breadcrumb.component';
|
||||||
|
|
||||||
|
describe('BreadcrumbComponent', () => {
|
||||||
|
let component: BreadcrumbComponent;
|
||||||
|
let fixture: ComponentFixture<BreadcrumbComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ BreadcrumbComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(BreadcrumbComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
|
||||||
|
|
||||||
|
import { filter } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { Breadcrumb } from './breadcrumb.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'mifosx-breadcrumb',
|
||||||
|
templateUrl: './breadcrumb.component.html',
|
||||||
|
styleUrls: ['./breadcrumb.component.scss']
|
||||||
|
})
|
||||||
|
export class BreadcrumbComponent implements OnInit {
|
||||||
|
|
||||||
|
breadcrumbs: Breadcrumb[];
|
||||||
|
|
||||||
|
constructor(private activatedRoute: ActivatedRoute,
|
||||||
|
private router: Router) {
|
||||||
|
this.generateBreadcrumbs();
|
||||||
|
}
|
||||||
|
|
||||||
|
generateBreadcrumbs() {
|
||||||
|
const routeDataBreadcrumb = 'breadcrumb';
|
||||||
|
const routeParamBreadcrumb = 'routeParamBreadcrumb';
|
||||||
|
const onNavigationEnd = this.router.events.pipe(filter(event => event instanceof NavigationEnd));
|
||||||
|
|
||||||
|
onNavigationEnd.subscribe(() => {
|
||||||
|
this.breadcrumbs = [];
|
||||||
|
let currentRoute = this.activatedRoute.root;
|
||||||
|
let url = '';
|
||||||
|
|
||||||
|
while (currentRoute.children.length > 0) {
|
||||||
|
const childrenRoutes = currentRoute.children;
|
||||||
|
let breadcrumbLabel = 'Home';
|
||||||
|
|
||||||
|
childrenRoutes.forEach(route => {
|
||||||
|
currentRoute = route;
|
||||||
|
if (route.outlet !== 'primary') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const hasData = (route.routeConfig && route.routeConfig.data);
|
||||||
|
if (hasData) {
|
||||||
|
if (route.snapshot.data.hasOwnProperty(routeParamBreadcrumb)) {
|
||||||
|
breadcrumbLabel = route.snapshot.params[route.snapshot.data[routeParamBreadcrumb]];
|
||||||
|
} else if (route.snapshot.data.hasOwnProperty(routeDataBreadcrumb)) {
|
||||||
|
breadcrumbLabel = route.snapshot.data[routeDataBreadcrumb];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const routeURL = route.snapshot.url.map(segment => segment.path).join('/');
|
||||||
|
url += `/${routeURL}`;
|
||||||
|
|
||||||
|
const breadcrumb: Breadcrumb = {
|
||||||
|
label: breadcrumbLabel,
|
||||||
|
url: url
|
||||||
|
};
|
||||||
|
|
||||||
|
if (breadcrumb.url !== '//home') {
|
||||||
|
this.breadcrumbs.push(breadcrumb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export interface Breadcrumb {
|
||||||
|
label: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
@@ -1,2 +1 @@
|
|||||||
<!-- TODO: Breadcrumb Links -->
|
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
<mifosx-toolbar [sidenav]="sidenav" (collapse)="toggleCollapse($event)"></mifosx-toolbar>
|
<mifosx-toolbar [sidenav]="sidenav" (collapse)="toggleCollapse($event)"></mifosx-toolbar>
|
||||||
|
|
||||||
|
<mifosx-breadcrumb></mifosx-breadcrumb>
|
||||||
<mifosx-content></mifosx-content>
|
<mifosx-content></mifosx-content>
|
||||||
|
|
||||||
</mat-sidenav-content>
|
</mat-sidenav-content>
|
||||||
|
|||||||
@@ -108,7 +108,7 @@
|
|||||||
|
|
||||||
<mat-menu #selfServiceMenu="matMenu" [overlapTrigger]="false">
|
<mat-menu #selfServiceMenu="matMenu" [overlapTrigger]="false">
|
||||||
<span (mouseleave)="selfServiceMenuTrigger.closeMenu()">
|
<span (mouseleave)="selfServiceMenuTrigger.closeMenu()">
|
||||||
<button mat-menu-item>User Management</button>
|
<button mat-menu-item routerLink="/self-service/users">User Management</button>
|
||||||
<button mat-menu-item>App Configuration</button>
|
<button mat-menu-item>App Configuration</button>
|
||||||
<button mat-menu-item>Task Management</button>
|
<button mat-menu-item>Task Management</button>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -11,17 +11,17 @@ const routes: Routes = [
|
|||||||
{
|
{
|
||||||
path: 'self-service/users',
|
path: 'self-service/users',
|
||||||
component: UserManagementComponent,
|
component: UserManagementComponent,
|
||||||
data: { title: extract('Self Service Users') }
|
data: { title: extract('Self Service Users'), breadcrumb: 'Self Service Users' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'self-service/users/create',
|
path: 'self-service/users/create',
|
||||||
component: CreateUserComponent,
|
component: CreateUserComponent,
|
||||||
data: { title: extract('Create Self Service User') }
|
data: { title: extract('Create Self Service User'), breadcrumb: 'Create' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'self-service/users/view',
|
path: 'self-service/users/view',
|
||||||
component: ViewUserComponent,
|
component: ViewUserComponent,
|
||||||
data: { title: extract('View Self Service User') }
|
data: { title: extract('View Self Service User'), breadcrumb: 'View' },
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
SELF SERVICE USER MANAGEMENT
|
||||||
<!-- <div class="fluid-container">
|
<!-- <div class="fluid-container">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="card mt-5">
|
<div class="card mt-5">
|
||||||
|
|||||||
Reference in New Issue
Block a user