import { Component , HostBinding , Input , OnDestroy , OnInit , ViewEncapsulation , ViewChild , HostListener } from '@angular/core' ; import { NavigationEnd , Router } from '@angular/router' ; import { MatMenuTrigger } from '@angular/material/menu' ; import { Subject } from 'rxjs' ; import { filter , takeUntil } from 'rxjs/operators' ; import { NotaddNavigationItem } from '@notadd/types' ; import { notaddAnimations } from '@notadd/animations' ; import { NotaddNavigationService } from '@notadd/components/navigation/navigation.service' ; import { NotaddConfigService } from '@notadd/services/config.service' ; import { RoutingPathPipe } from '@notadd/pipes/routing-path.pipe' ; @ Component ( { selector : 'notadd-nav-collapse' , templateUrl : './nav-collapse.component.html' , styleUrls : [ './nav-collapse.component.scss' ] , animations : notaddAnimations , providers : [ RoutingPathPipe ] } ) export class NotaddNavCollapseComponent implements OnInit , OnDestroy { @ Input ( ) item : NotaddNavigationItem ; @ HostBinding ( 'class' ) classes = 'nav-collapsable nav-item' ; @ HostBinding ( 'class.open' ) isCollapsed = false ; @ ViewChild ( MatMenuTrigger , { static : false } ) menuTrigger : MatMenuTrigger ; notaddConfig : any ; subMenus : Array < any > ; isEnterNavMenu : boolean ; private ngUnsubscribe : Subject < any > ; constructor ( private navigationService , private configService , private router , private path ) { this . ngUnsubscribe = new Subject < any > ( ) ; this . subMenus = [ ] ; } ngOnInit ( ) { this . router . events . pipe ( filter ( event => event instanceof NavigationEnd ) , takeUntil ( this . ngUnsubscribe ) ) . subscribe ( ( event ) => { this . changeCollapse ( ! this . isUrlInChildren ( this . item , event . urlAfterRedirects ) ) ; } ) ; this . navigationService . onItemCollapsed . pipe ( takeUntil ( this . ngUnsubscribe ) ) . subscribe ( ( clickedItem ) => { if ( clickedItem && clickedItem . children ) { if ( this . isChildrenOf ( this . item , clickedItem ) ) { return ; } if ( this . isUrlInChildren ( this . item , this . router . url ) ) { return ; } if ( this . item . id !== clickedItem . id ) { this . changeCollapse ( true ) ; } } } ) ; this . configService . config . pipe ( takeUntil ( this . ngUnsubscribe ) ) . subscribe ( ( config ) => { this . notaddConfig = config ; } ) ; this . changeCollapse ( this . isUrlInChildren ( this . item , this . router . url ) ) ; } ngOnDestroy ( ) { this . ngUnsubscribe . next ( ) ; this . ngUnsubscribe . complete ( ) ; } param event toggleCollapse ( event ) { event . preventDefault ( ) ; this . isCollapsed = ! this . isCollapsed ; this . navigationService . onItemCollapsed . next ( this . item ) ; this . navigationService . onItemCollapseToggled . next ( ) ; } openNavMenu ( event ) { event . preventDefault ( ) ; this . menuTrigger . openMenu ( ) ; } closeNavMenu ( event ) { event . preventDefault ( ) ; setTimeout ( ( ) => { ! this . isEnterNavMenu && this . menuTrigger . closeMenu ( ) ; } , 100 ) ; } param isCollapsed changeCollapse ( isCollapsed ) { if ( this . isCollapsed !== isCollapsed ) { return ; } this . isCollapsed = ! isCollapsed ; this . navigationService . onItemCollapseToggled . next ( ) ; } param parent param item returns { boolean } isChildrenOf ( parent , item ) { if ( ! parent . children ) { return false ; } if ( ~ parent . children . indexOf ( item ) ) { return true ; } for ( const children of parent . children ) { if ( children . children ) { return this . isChildrenOf ( children , item ) ; } } } param parent param url returns { boolean } isUrlInChildren ( parent , url ) { if ( ! parent . children ) { return false ; } for ( let i = 0 ; i < parent . children . length ; i ++ ) { if ( parent . children [ i ] . children ) { if ( this . isUrlInChildren ( parent . children [ i ] , url ) ) { return true ; } } const childrenUrl = this . path . transform ( parent . children [ i ] . url , parent . children [ i ] . urlParam ) ; if ( childrenUrl === url || url . includes ( childrenUrl ) ) { return true ; } } return false ; } setSubMenu ( menu ) { this . subMenus = menu . children ; } }