1+ import { select } from '@ngxs/store' ;
2+
13import { filter , map , startWith } from 'rxjs' ;
24
35import { Component , computed , inject } from '@angular/core' ;
46import { toSignal } from '@angular/core/rxjs-interop' ;
5- import { ActivatedRoute , NavigationEnd , Router } from '@angular/router' ;
7+ import { ActivatedRoute , ActivatedRouteSnapshot , NavigationEnd , Router } from '@angular/router' ;
68
9+ import { ProviderSelectors } from '@core/store/provider' ;
710import { RouteData } from '@osf/core/models' ;
11+ import { InstitutionsAdminSelectors } from '@osf/features/admin-institutions/store' ;
812import { IconComponent } from '@osf/shared/components' ;
13+ import { InstitutionsSearchSelectors } from '@shared/stores/institutions-search' ;
914
1015@Component ( {
1116 selector : 'osf-breadcrumb' ,
@@ -17,14 +22,9 @@ export class BreadcrumbComponent {
1722 private readonly router = inject ( Router ) ;
1823 private readonly route = inject ( ActivatedRoute ) ;
1924
20- readonly url = toSignal (
21- this . router . events . pipe (
22- filter ( ( event ) => event instanceof NavigationEnd ) ,
23- map ( ( ) => this . router . url ) ,
24- startWith ( this . router . url )
25- ) ,
26- { initialValue : this . router . url }
27- ) ;
25+ currentProvider = select ( ProviderSelectors . getCurrentProvider ) ;
26+ institution = select ( InstitutionsSearchSelectors . getInstitution ) ;
27+ institutionDashboard = select ( InstitutionsAdminSelectors . getInstitution ) ;
2828
2929 readonly routeData = toSignal (
3030 this . router . events . pipe (
@@ -37,13 +37,48 @@ export class BreadcrumbComponent {
3737
3838 readonly showBreadcrumb = computed ( ( ) => this . routeData ( ) ?. skipBreadcrumbs !== true ) ;
3939
40- readonly parsedUrl = computed ( ( ) =>
41- this . url ( )
42- . split ( '?' ) [ 0 ]
43- . split ( '/' )
44- . filter ( Boolean )
45- . map ( ( segment ) => segment . replace ( / - / g, ' ' ) )
46- ) ;
40+ readonly breadcrumbs = computed < string [ ] > ( ( ) => {
41+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
42+ const currentRoute = this . routeData ( ) ; // Trigger recomputation when route data changes
43+ const providerName = this . currentProvider ( ) ?. name ;
44+ const institution = this . institution ( ) ?. name ;
45+ const institutionDashboard = this . institutionDashboard ( ) ?. name ;
46+
47+ return this . buildBreadcrumbs ( this . route . root . snapshot , providerName , institution ?? institutionDashboard ) ;
48+ } ) ;
49+
50+ private buildBreadcrumbs (
51+ route : ActivatedRouteSnapshot ,
52+ providerName : string | undefined ,
53+ institutionName : string | undefined ,
54+ segments : string [ ] = [ ]
55+ ) : string [ ] {
56+ for ( const segment of route . url ) {
57+ const segmentPath = segment . path ;
58+ let label = segmentPath . replace ( / - / g, ' ' ) ;
59+
60+ const isProviderIdSegment = route . params [ 'providerId' ] === segmentPath ;
61+ const isInstitutionIdSegment = route . params [ 'institutionId' ] === segmentPath ;
62+
63+ if ( isProviderIdSegment && providerName ) {
64+ label = providerName ;
65+ }
66+
67+ if ( isInstitutionIdSegment && institutionName ) {
68+ label = institutionName ;
69+ }
70+
71+ if ( label && label . trim ( ) . length > 0 ) {
72+ segments . push ( label ) ;
73+ }
74+ }
75+
76+ if ( route . firstChild ) {
77+ return this . buildBreadcrumbs ( route . firstChild , providerName , institutionName , segments ) ;
78+ }
79+
80+ return segments ;
81+ }
4782
4883 private getCurrentRouteData ( ) : RouteData {
4984 let currentRoute = this . route ;
0 commit comments