import { combineLatest , Observable , ReplaySubject } from 'rxjs' ; import { map , scan , shareReplay , switchMap } from 'rxjs/operators' ; export interface NavigationSection { label : string | undefined ; sortKey : number ; entries : NavigationEntry [ ] ; } export interface NavigationEntry { label : string ; app : string ; path : string ; matchFullPath ? : boolean ; ignoreTrailingSlash ? : boolean ; onClick ? : ( event : React . MouseEvent < HTMLElement | HTMLButtonElement , MouseEvent > ) => void ; isNewFeature ? : boolean ; } export interface NavigationRegistry { registerSections : ( sections$ : Observable < NavigationSection [ ] > ) => void ; sections$ : Observable < NavigationSection [ ] > ; } export const createNavigationRegistry = ( ) : NavigationRegistry => { const registeredSections$ = new ReplaySubject < Observable < NavigationSection [ ] > > ( ) ; const registerSections = ( sections$ ) => { registeredSections$ . next ( sections$ ) ; } ; const sections$ = registeredSections$ . pipe ( scan ( ( accumulatedSections$ , newSections ) => accumulatedSections$ . add ( newSections ) , new Set < Observable < NavigationSection [ ] > > ( ) ) , switchMap ( ( registeredSections ) => combineLatest ( [ ... registeredSections ] ) ) , map ( ( registeredSections ) => registeredSections . flat ( ) . sort ( ( first , second ) => first . sortKey - second . sortKey ) ) , shareReplay ( 1 ) ) ; return { registerSections , sections$ , } ; } ;