import { ChangeDetectorRef , Component , HostBinding , Input , OnDestroy , OnInit } from '@angular/core' ; import { NavigationEnd , Router } from '@angular/router' ; import { merge , Subject } from 'rxjs' ; import { filter , takeUntil } from 'rxjs/operators' ; import { FuseNavigationItem } from '@fuse/types' ; import { fuseAnimations } from '@fuse/animations' ; import { FuseNavigationService } from '@fuse/components/navigation/navigation.service' ; @ Component ( { selector : 'fuse-nav-vertical-collapsable' , templateUrl : './collapsable.component.html' , styleUrls : [ './collapsable.component.scss' ] , animations : fuseAnimations } ) export class FuseNavVerticalCollapsableComponent implements OnInit , OnDestroy { @ Input ( ) item : FuseNavigationItem ; @ HostBinding ( 'class' ) classes = 'nav-collapsable nav-item' ; @ HostBinding ( 'class.open' ) public isOpen = false ; private _unsubscribeAll : Subject < any > ; param { ChangeDetectorRef } _changeDetectorRef param { FuseNavigationService } _fuseNavigationService param { Router } _router constructor ( private _changeDetectorRef , private _fuseNavigationService , private _router ) { this . _unsubscribeAll = new Subject ( ) ; } /**
     * On init
     */ ngOnInit ( ) { this . _router . events . pipe ( filter ( event => event instanceof NavigationEnd ) , takeUntil ( this . _unsubscribeAll ) ) . subscribe ( ( event ) => { if ( this . isUrlInChildren ( this . item , event . urlAfterRedirects ) ) { this . expand ( ) ; } else { this . collapse ( ) ; } } ) ; this . _fuseNavigationService . onItemCollapsed . pipe ( takeUntil ( this . _unsubscribeAll ) ) . 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 !== clickedItem ) { this . collapse ( ) ; } } } ) ; if ( this . isUrlInChildren ( this . item , this . _router . url ) ) { this . expand ( ) ; } else { this . collapse ( ) ; } merge ( this . _fuseNavigationService . onNavigationItemAdded , this . _fuseNavigationService . onNavigationItemUpdated , this . _fuseNavigationService . onNavigationItemRemoved ) . pipe ( takeUntil ( this . _unsubscribeAll ) ) . subscribe ( ( ) => { this . _changeDetectorRef . markForCheck ( ) ; } ) ; } /**
     * On destroy
     */ ngOnDestroy ( ) { this . _unsubscribeAll . next ( ) ; this . _unsubscribeAll . complete ( ) ; } param ev toggleOpen ( ev ) { ev . preventDefault ( ) ; this . isOpen = ! this . isOpen ; this . _fuseNavigationService . onItemCollapsed . next ( this . item ) ; this . _fuseNavigationService . onItemCollapseToggled . next ( ) ; } /**
     * Expand the collapsable navigation
     */ expand ( ) { if ( this . isOpen ) { return ; } this . isOpen = true ; this . _changeDetectorRef . markForCheck ( ) ; this . _fuseNavigationService . onItemCollapseToggled . next ( ) ; } /**
     * Collapse the collapsable navigation
     */ collapse ( ) { if ( ! this . isOpen ) { return ; } this . isOpen = false ; this . _changeDetectorRef . markForCheck ( ) ; this . _fuseNavigationService . onItemCollapseToggled . next ( ) ; } param parent param item returns { boolean } isChildrenOf ( parent , item ) { if ( ! parent . children ) { return false ; } if ( parent . children . indexOf ( item ) !== - 1 ) { 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 ; } } if ( parent . children [ i ] . url === url || url . includes ( parent . children [ i ] . url ) ) { return true ; } } return false ; } }