Skip to content

Commit 232289a

Browse files
committed
refactor(breadcrumb-router): migrate breadcrumbs$ toSignal, use attrib prop for breadcrumb item, test update, cleanup
1 parent b487e4c commit 232289a

File tree

3 files changed

+16
-41
lines changed

3 files changed

+16
-41
lines changed

projects/coreui-angular/src/lib/breadcrumb/breadcrumb-router/breadcrumb-router.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<c-breadcrumb class="m-0">
2-
@for (breadcrumb of breadcrumbs | async; track breadcrumb; let last = $last) {
2+
@for (breadcrumb of breadcrumbs(); track breadcrumb; let last = $last) {
33
@if (breadcrumb?.label && (breadcrumb?.url?.slice(-1) === '/' || last)) {
44
<c-breadcrumb-item
55
[active]="last"
66
[url]="breadcrumb?.url"
7-
[attributes]="breadcrumb?.attributes"
7+
[attribs]="breadcrumb?.attributes"
88
[linkProps]="breadcrumb?.linkProps"
99
>
1010
{{ breadcrumb?.label }}

projects/coreui-angular/src/lib/breadcrumb/breadcrumb-router/breadcrumb-router.component.spec.ts

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { ComponentRef } from '@angular/core';
22
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
33
import { provideRouter, Route } from '@angular/router';
44
import { RouterTestingHarness } from '@angular/router/testing';
5-
import { take } from 'rxjs';
65

76
import { BreadcrumbRouterComponent } from './breadcrumb-router.component';
87
import { BreadcrumbRouterService } from './breadcrumb-router.service';
@@ -40,33 +39,25 @@ describe('BreadcrumbComponent', () => {
4039
});
4140

4241
it('should have breadcrumbs', () => {
43-
expect(component.breadcrumbs).toBeDefined();
42+
expect(component.breadcrumbs()).toBeDefined();
4443
});
4544

4645
it('should get breadcrumbs from service', async () => {
4746
const comp = await harness.navigateByUrl('/home');
48-
component.breadcrumbs?.pipe(take(1)).subscribe((breadcrumbs) => {
49-
expect(breadcrumbs).toEqual([{ label: 'Home', url: '/home', queryParams: {} }]);
50-
});
47+
expect(component.breadcrumbs()).toEqual([{ label: 'Home', url: '/home', queryParams: {} }]);
5148
});
5249
it('should get breadcrumbs from service', async () => {
5350
const comp = await harness.navigateByUrl('/color?id=1&test=2');
54-
component.breadcrumbs?.pipe(take(1)).subscribe((breadcrumbs) => {
55-
expect(breadcrumbs).toEqual([{ label: 'Color', url: '/color', queryParams: { id: '1', test: '2' } }]);
56-
});
51+
expect(component.breadcrumbs()).toEqual([{ label: 'Color', url: '/color', queryParams: { id: '1', test: '2' } }]);
5752
});
5853
it('should get breadcrumbs from service', async () => {
5954
const comp = await harness.navigateByUrl('/');
60-
component.breadcrumbs?.pipe(take(1)).subscribe((breadcrumbs) => {
61-
expect(breadcrumbs).toEqual([{ label: '', url: '/', queryParams: {} }]);
62-
});
55+
expect(component.breadcrumbs()).toEqual([{ label: '', url: '/', queryParams: {} }]);
6356
});
6457

6558
it('should emit breadcrumbs on items change', () => {
66-
componentRef.setInput('items', [{ label: 'test' }]);
59+
componentRef.setInput('items', [{ label: 'test', url: '/color', attributes: { title: 'test' } }]);
6760
fixture.detectChanges();
68-
component.breadcrumbs?.pipe(take(1)).subscribe((breadcrumbs) => {
69-
expect(breadcrumbs).toEqual([{ label: 'test' }]);
70-
});
61+
expect(component.breadcrumbs()).toEqual([{ label: 'test', url: '/color', attributes: { title: 'test' } }]);
7162
});
7263
});
Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { Component, effect, inject, input, OnDestroy, OnInit } from '@angular/core';
2-
import { Observable, Observer } from 'rxjs';
3-
import { AsyncPipe } from '@angular/common';
1+
import { Component, computed, inject, input } from '@angular/core';
2+
import { toSignal } from '@angular/core/rxjs-interop';
43

54
import { IBreadcrumbItem } from '../breadcrumb-item/breadcrumb-item';
65
import { BreadcrumbComponent } from '../breadcrumb/breadcrumb.component';
@@ -10,35 +9,20 @@ import { BreadcrumbItemComponent } from '../breadcrumb-item/breadcrumb-item.comp
109
@Component({
1110
selector: 'c-breadcrumb-router, [cBreadcrumbRouter]',
1211
templateUrl: './breadcrumb-router.component.html',
13-
imports: [BreadcrumbComponent, BreadcrumbItemComponent, AsyncPipe]
12+
imports: [BreadcrumbComponent, BreadcrumbItemComponent]
1413
})
15-
export class BreadcrumbRouterComponent implements OnDestroy, OnInit {
16-
readonly service = inject(BreadcrumbRouterService);
14+
export class BreadcrumbRouterComponent {
15+
readonly #breadcrumbRouterService = inject(BreadcrumbRouterService);
1716

1817
/**
1918
* Optional array of IBreadcrumbItem to override default BreadcrumbRouter behavior. [docs]
2019
* @return IBreadcrumbItem[]
2120
*/
2221
readonly items = input<IBreadcrumbItem[]>();
23-
public breadcrumbs: Observable<IBreadcrumbItem[]> | undefined;
2422

25-
ngOnInit(): void {
26-
this.breadcrumbs = this.service.breadcrumbs$;
27-
}
23+
readonly #breadcrumbs = toSignal(this.#breadcrumbRouterService.breadcrumbs$);
2824

29-
readonly setup = effect(() => {
30-
const items = this.items();
31-
if (items && items.length > 0) {
32-
this.breadcrumbs = new Observable<IBreadcrumbItem[]>((observer: Observer<IBreadcrumbItem[]>) => {
33-
const itemsValue = this.items();
34-
if (itemsValue) {
35-
observer.next(itemsValue);
36-
}
37-
});
38-
}
25+
readonly breadcrumbs = computed(() => {
26+
return this.items() ?? this.#breadcrumbs() ?? [];
3927
});
40-
41-
ngOnDestroy(): void {
42-
this.breadcrumbs = undefined;
43-
}
4428
}

0 commit comments

Comments
 (0)