Add LinkComponent, integrate with Home and Shell components, and enhance navigation structure
This commit is contained in:
parent
f391db4fba
commit
40fde36bc6
@ -3,7 +3,7 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "ng serve",
|
"start": "ng serve --host 0.0.0.0",
|
||||||
"build": "ng build",
|
"build": "ng build",
|
||||||
"watch": "ng build --watch --configuration development",
|
"watch": "ng build --watch --configuration development",
|
||||||
"test": "ng test"
|
"test": "ng test"
|
||||||
@ -38,4 +38,4 @@
|
|||||||
"karma-jasmine-html-reporter": "~2.1.0",
|
"karma-jasmine-html-reporter": "~2.1.0",
|
||||||
"typescript": "~5.9.3"
|
"typescript": "~5.9.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,12 +19,26 @@ export const routes: Routes = [
|
|||||||
title: 'Home',
|
title: 'Home',
|
||||||
path: '',
|
path: '',
|
||||||
component: HomeComponent,
|
component: HomeComponent,
|
||||||
|
data: { showInNav: true }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Dashboard',
|
||||||
|
path: 'dashboard',
|
||||||
|
component: HomeComponent,
|
||||||
|
data: { showInNav: true },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
title: 'Test',
|
||||||
|
path: 'test',
|
||||||
|
component: HomeComponent,
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
canActivate: [authGuard],
|
canActivate: [authGuard],
|
||||||
resolve: {
|
resolve: {
|
||||||
user: subjectResolver,
|
user: subjectResolver,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '**',
|
path: '**',
|
||||||
|
|||||||
@ -1 +1,121 @@
|
|||||||
|
<app-link href="/dashboard/test">test</app-link>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
|
<p>home works!</p>
|
||||||
<p>home works!</p>
|
<p>home works!</p>
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
import {LinkComponent} from '../link/link.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-home',
|
selector: 'app-home',
|
||||||
imports: [],
|
imports: [
|
||||||
|
LinkComponent
|
||||||
|
],
|
||||||
templateUrl: './home.component.html',
|
templateUrl: './home.component.html',
|
||||||
styleUrl: './home.component.scss',
|
styleUrl: './home.component.scss',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
<a [href]="href()" (click)="click($event)"><ng-content></ng-content></a>
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { LinkComponent } from './link.component';
|
||||||
|
|
||||||
|
describe('LinkComponent', () => {
|
||||||
|
let component: LinkComponent;
|
||||||
|
let fixture: ComponentFixture<LinkComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [LinkComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(LinkComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
import {Component, inject, input} from '@angular/core';
|
||||||
|
import {Router} from '@angular/router';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-link',
|
||||||
|
imports: [],
|
||||||
|
templateUrl: './link.component.html',
|
||||||
|
styleUrl: './link.component.scss'
|
||||||
|
})
|
||||||
|
export class LinkComponent {
|
||||||
|
|
||||||
|
public href = input.required<string>();
|
||||||
|
public external = input<boolean>(false);
|
||||||
|
|
||||||
|
private router = inject(Router);
|
||||||
|
|
||||||
|
click($event: PointerEvent) {
|
||||||
|
if (!this.external()) {
|
||||||
|
$event.preventDefault();
|
||||||
|
this.router.navigate([this.href()]).then();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
<div class="drawer-container">
|
||||||
|
<ng-content select="drawer-content"></ng-content>
|
||||||
|
</div>
|
||||||
|
<div class="main-content-container">
|
||||||
|
<div class="top-nav-container">
|
||||||
|
<ng-content select="top-nav-container"></ng-content>
|
||||||
|
</div>
|
||||||
|
<div class="top-nav-breadcrumb-container">
|
||||||
|
<ng-content select="top-nav-breadcrumb"></ng-content>
|
||||||
|
</div>
|
||||||
|
<div class="content-container">
|
||||||
|
<router-outlet/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.drawer-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content-container{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 1rem 0 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-container {
|
||||||
|
background-color: var(--neutral-70);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content-container {
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
.top-nav-breadcrumb-container, .top-nav-container {
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-nav-breadcrumb-container {
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
border-bottom: 1px solid var(--neutral-70);
|
||||||
|
border-top: 1px solid var(--neutral-70);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-container {
|
||||||
|
padding-top: 1rem;
|
||||||
|
padding-right: 1rem;
|
||||||
|
flex-grow: 1;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { DrawerComponent } from './drawer.component';
|
||||||
|
|
||||||
|
describe('DrawerComponent', () => {
|
||||||
|
let component: DrawerComponent;
|
||||||
|
let fixture: ComponentFixture<DrawerComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [DrawerComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(DrawerComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import {RouterOutlet} from '@angular/router';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-drawer',
|
||||||
|
imports: [
|
||||||
|
RouterOutlet
|
||||||
|
],
|
||||||
|
templateUrl: './drawer.component.html',
|
||||||
|
styleUrl: './drawer.component.scss'
|
||||||
|
})
|
||||||
|
export class DrawerComponent {
|
||||||
|
|
||||||
|
}
|
||||||
@ -2,4 +2,4 @@
|
|||||||
<span>{{user()}}</span>
|
<span>{{user()}}</span>
|
||||||
<a href="" (click)="logout($event)">Logout</a>
|
<a href="" (click)="logout($event)">Logout</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="profile-picture neutral-30"></div>
|
<div class="profile-picture neutral-70"></div>
|
||||||
|
|||||||
@ -15,5 +15,6 @@
|
|||||||
height: 3rem;
|
height: 3rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: var(--bg-color);
|
background-color: var(--bg-color);
|
||||||
|
border-radius: 0.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,36 @@
|
|||||||
<app-panel class="shell-nav-bar neutral-20">
|
<app-drawer>
|
||||||
<app-icon path="/full_logo.svg" class="logo primary-icon-50"></app-icon>
|
<div class="drawer-content" ngProjectAs="drawer-content">
|
||||||
<app-nav-profile></app-nav-profile>
|
|
||||||
</app-panel>
|
<app-icon path="/full_logo.svg" class="logo primary-icon-50"></app-icon>
|
||||||
|
|
||||||
|
<div class="nav-links">
|
||||||
|
@for (link of navLinks(); track link.label) {
|
||||||
|
<app-link [href]="link.url">
|
||||||
|
<span [ngClass]="{'active': activeTopLevelUrl() === link.url}" class="nav-link">{{link.label}}</span>
|
||||||
|
</app-link>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="top-nav-container" ngProjectAs="top-nav-container">
|
||||||
|
<span class="title">{{ title() }}</span>
|
||||||
|
<app-nav-profile></app-nav-profile>
|
||||||
|
</div>
|
||||||
|
<div class="top-nav-breadcrumb" ngProjectAs="top-nav-breadcrumb">
|
||||||
|
|
||||||
|
<span> / </span>
|
||||||
|
|
||||||
|
@for (crumb of breadcrumbs(); let last = $last; track crumb.label) {
|
||||||
|
|
||||||
|
@if (crumb.url && !last) {
|
||||||
|
<a [routerLink]="crumb.url">{{ crumb.label }}</a>
|
||||||
|
} @else {
|
||||||
|
<span>{{ crumb.label }}</span>
|
||||||
|
}
|
||||||
|
@if (!last) {
|
||||||
|
<span> / </span>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</app-drawer>
|
||||||
|
|||||||
@ -1,9 +1,62 @@
|
|||||||
.shell-nav-bar {
|
:host {
|
||||||
.logo {
|
height: 100vh;
|
||||||
$height: 3rem;
|
width: 100vw;
|
||||||
height: $height;
|
display: block;
|
||||||
width: #{$height * 3.356876171875};
|
|
||||||
|
.top-nav-container {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
app-nav-profile {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.drawer-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
.logo {
|
||||||
|
$height: 3rem;
|
||||||
|
height: $height;
|
||||||
|
width: #{$height * 3.356876171875};
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
border-bottom: 1px solid var(--neutral-60);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-links {
|
||||||
|
margin-top: 1rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
padding: 0.5rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
|
||||||
|
&:hover, &.active {
|
||||||
|
background-color: var(--neutral-60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::ng-deep app-link {
|
||||||
|
a {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
color: unset;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.shell-nav-bar {
|
||||||
|
|
||||||
app-nav-profile {
|
app-nav-profile {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,21 +1,111 @@
|
|||||||
import {Component, computed, inject} from '@angular/core';
|
import {Component, computed, OnInit, signal} from '@angular/core';
|
||||||
import {NavProfileComponent} from './nav-profile/nav-profile.component';
|
import {NavProfileComponent} from './nav-profile/nav-profile.component';
|
||||||
import {ActivatedRoute, RouterOutlet} from '@angular/router';
|
import {ActivatedRoute, NavigationEnd, Route, Router, RouterLink} from '@angular/router';
|
||||||
import {PanelComponent} from '../panel/panel.component';
|
|
||||||
import {IconComponent} from '../icon/icon.component';
|
import {IconComponent} from '../icon/icon.component';
|
||||||
import {toSignal} from '@angular/core/rxjs-interop';
|
import {DrawerComponent} from './drawer/drawer.component';
|
||||||
|
import {filter} from 'rxjs';
|
||||||
|
import {NgClass} from '@angular/common';
|
||||||
|
import {LinkComponent} from '../link/link.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-shell',
|
selector: 'app-shell',
|
||||||
imports: [
|
imports: [
|
||||||
NavProfileComponent,
|
NavProfileComponent,
|
||||||
PanelComponent,
|
IconComponent,
|
||||||
IconComponent
|
DrawerComponent,
|
||||||
|
RouterLink,
|
||||||
|
NgClass,
|
||||||
|
LinkComponent
|
||||||
],
|
],
|
||||||
templateUrl: './shell.component.html',
|
templateUrl: './shell.component.html',
|
||||||
styleUrl: './shell.component.scss',
|
styleUrl: './shell.component.scss',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
})
|
})
|
||||||
export class ShellComponent {
|
export class ShellComponent implements OnInit {
|
||||||
|
|
||||||
|
protected breadcrumbs = signal<Breadcrumb[]>([]);
|
||||||
|
protected navLinks = signal<Breadcrumb[]>([]);
|
||||||
|
|
||||||
|
protected title = computed<string>(() => {
|
||||||
|
return this.breadcrumbs()[this.breadcrumbs().length - 1]?.label || 'Undefined';
|
||||||
|
});
|
||||||
|
|
||||||
|
protected activeTopLevelUrl = computed<string | null>(() => {
|
||||||
|
const breadcrumbs = this.breadcrumbs();
|
||||||
|
|
||||||
|
if (breadcrumbs.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.breadcrumbs()[0]?.url;
|
||||||
|
});
|
||||||
|
|
||||||
|
constructor(private router: Router, private route: ActivatedRoute) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
|
||||||
|
this.initNavigation();
|
||||||
|
this.initBreadcrumbs();
|
||||||
|
|
||||||
|
|
||||||
|
this.router.events
|
||||||
|
.pipe(filter(event => event instanceof NavigationEnd))
|
||||||
|
.subscribe(() => {
|
||||||
|
this.initBreadcrumbs();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private initBreadcrumbs() {
|
||||||
|
this.breadcrumbs.set(this.buildBreadcrumbs(this.route.root));
|
||||||
|
console.log('breadcrumbs', this.breadcrumbs());
|
||||||
|
}
|
||||||
|
|
||||||
|
private initNavigation() {
|
||||||
|
this.navLinks.set(this.extractNavLinks(this.router.config));
|
||||||
|
console.log('navLinks', this.navLinks())
|
||||||
|
}
|
||||||
|
|
||||||
|
private extractNavLinks(routes: Route[]): Breadcrumb[] {
|
||||||
|
return routes
|
||||||
|
.filter(r => r.path === '')
|
||||||
|
.flatMap(r => r.children ?? [])
|
||||||
|
.filter(r => r.data?.['showInNav'])
|
||||||
|
.map(r => ({
|
||||||
|
label: r.data?.['title'] || r.title || '',
|
||||||
|
url: '/' + (r.path ?? '')
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildBreadcrumbs(route: ActivatedRoute, url: string = '/', breadcrumbs: Breadcrumb[] = []): Breadcrumb[] {
|
||||||
|
const children = route.children;
|
||||||
|
|
||||||
|
if (children.length === 0) {
|
||||||
|
return breadcrumbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
const child = children[0];
|
||||||
|
|
||||||
|
const routeURL = child.snapshot.url.map(segment => segment.path).join('/');
|
||||||
|
if (routeURL) {
|
||||||
|
url += `${routeURL}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const label =
|
||||||
|
child.snapshot.data['title'] ||
|
||||||
|
child.snapshot.routeConfig?.title ||
|
||||||
|
'';
|
||||||
|
|
||||||
|
if (label) {
|
||||||
|
breadcrumbs.push({ label, url });
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.buildBreadcrumbs(child, url, breadcrumbs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Breadcrumb {
|
||||||
|
label: string = 'undefined';
|
||||||
|
url: string = '';
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user