import { sortBy } from 'lodash' ; import { BehaviorSubject , Observable , ReplaySubject } from 'rxjs' ; import { map , takeUntil } from 'rxjs/operators' ; import { InternalApplicationStart , PublicAppDeepLinkInfo , PublicAppInfo } from '../../application' ; import { HttpStart , IBasePath } from '../../http' ; import { ChromeNavLink , NavLinkWrapper } from './nav_link' ; import { toNavLink } from './to_nav_link' ; interface StartDeps { application : InternalApplicationStart ; http : HttpStart ; } /**
 *  ChromeNavLinks for manipulating nav links.
 *
 *  public export interface ChromeNavLinks { /**
     * Get an observable for a sorted list of navlinks.
     */ getNavLinks$ ( ) : Observable < Array < Readonly < ChromeNavLink > > > ; param id get ( id ) : ChromeNavLink | undefined ; /**
     * Get the current state of all navlinks.
     */ getAll ( ) : Array < Readonly < ChromeNavLink > > ; param id has ( id ) : boolean ; remarks enableForcedAppSwitcherNavigation ( ) : void ; /**
     * An observable of the forced app switcher state.
     */ getForceAppSwitcherNavigation$ ( ) : Observable < boolean > ; } export class NavLinksService { private readonly stop$ = new ReplaySubject ( 1 ) ; public start ( { application , http } ) { const navLinks$ = new BehaviorSubject < ReadonlyMap < string , NavLinkWrapper > > ( new Map ( ) ) ; application . applications$ . pipe ( map ( ( apps ) => { return new Map ( [ ... apps ] . filter ( ( [ , app ] ) => ! app . chromeless ) . reduce ( ( navLinks , [ appId , app ] ) => { navLinks . push ( [ appId , toNavLink ( app , http . basePath ) ] , ... toNavDeepLinks ( app , app . deepLinks , http . basePath ) ) ; return navLinks ; } , [ ] ) ) ; } ) ) . subscribe ( ( navlinks ) => { navLinks$ . next ( navlinks ) ; } ) ; const forceAppSwitcherNavigation$ = new BehaviorSubject ( false ) ; return { getNavLinks$ : ( ) => { return navLinks$ . pipe ( map ( sortNavLinks ) , takeUntil ( this . stop$ ) ) ; } , get ( id ) { const link = navLinks$ . value . get ( id ) ; return link && link . properties ; } , getAll ( ) { return sortNavLinks ( navLinks$ . value ) ; } , has ( id ) { return navLinks$ . value . has ( id ) ; } , enableForcedAppSwitcherNavigation ( ) { forceAppSwitcherNavigation$ . next ( true ) ; } , getForceAppSwitcherNavigation$ ( ) { return forceAppSwitcherNavigation$ . asObservable ( ) ; } , } ; } public stop ( ) { this . stop$ . next ( ) ; } } function sortNavLinks ( navLinks ) { return sortBy ( [ ... navLinks . values ( ) ] . map ( ( link ) => link . properties ) , 'order' ) ; } function toNavDeepLinks ( app , deepLinks , basePath ) { if ( ! deepLinks ) { return [ ] ; } return deepLinks . reduce ( ( navDeepLinks , deepLink ) => { const id = `${ app . id }:${ deepLink . id }` ; if ( deepLink . path ) { navDeepLinks . push ( [ id , toNavLink ( app , basePath , { ... deepLink , id } ) ] ) ; } navDeepLinks . push ( ... toNavDeepLinks ( app , deepLink . deepLinks , basePath ) ) ; return navDeepLinks ; } , [ ] ) ; }