import { Directive , Input , OnInit , OnDestroy , HostListener } from '@angular/core' ; import { Router , NavigationEnd , PRIMARY_OUTLET } from '@angular/router' ; import { filter , takeUntil } from 'rxjs/operators' ; import { Subject } from 'rxjs' ; import { Store } from '@ngrx/store' ; @ Directive ( { selector : '[acaMenuPanel]' , exportAs : 'acaMenuPanel' } ) export class MenuPanelDirective implements OnInit , OnDestroy { @ Input ( ) acaMenuPanel ; hasActiveChildren = false ; private onDestroy$ : Subject < boolean > = new Subject < boolean > ( ) ; @ HostListener ( 'menuOpened' ) menuOpened ( ) { if ( this . acaMenuPanel . children && ! this . hasActiveLinks ( ) ) { const firstChild = this . acaMenuPanel . children [ 0 ] ; if ( firstChild . url ) { this . router . navigate ( this . getNavigationCommands ( firstChild . url ) ) ; } else { this . store . dispatch ( { type : firstChild . action . action , payload : this . getNavigationCommands ( firstChild . action . payload ) } ) ; } } } constructor ( private store , private router ) { } hasActiveLinks ( ) { if ( this . acaMenuPanel && this . acaMenuPanel . children ) { return this . acaMenuPanel . children . some ( ( child ) => { return this . router . url . startsWith ( child . url || child . action . payload ) ; } ) ; } return false ; } ngOnInit ( ) { this . hasActiveChildren = this . hasActiveLinks ( ) ; this . router . events . pipe ( filter ( ( event ) => event instanceof NavigationEnd ) , takeUntil ( this . onDestroy$ ) ) . subscribe ( ( ) => { this . hasActiveChildren = this . hasActiveLinks ( ) ; } ) ; } ngOnDestroy ( ) { this . onDestroy$ . next ( true ) ; this . onDestroy$ . complete ( ) ; } private getNavigationCommands ( url ) { const urlTree = this . router . parseUrl ( url ) ; const urlSegmentGroup = urlTree . root . children [ PRIMARY_OUTLET ] ; if ( ! urlSegmentGroup ) { return [ url ] ; } const urlSegments = urlSegmentGroup . segments ; return urlSegments . reduce ( function ( acc , item ) { acc . push ( item . path , item . parameters ) ; return acc ; } , [ ] ) ; } }