mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-04-14 12:25:14 +00:00
238 lines
6.1 KiB
TypeScript
238 lines
6.1 KiB
TypeScript
import { Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core';
|
|
import { NavigationEnd, Router } from '@angular/router';
|
|
import { 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
|
|
private _unsubscribeAll: Subject<any>;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param {FuseNavigationService} _fuseNavigationService
|
|
* @param {Router} _router
|
|
*/
|
|
constructor(
|
|
private _fuseNavigationService: FuseNavigationService,
|
|
private _router: Router
|
|
)
|
|
{
|
|
// Set the private defaults
|
|
this._unsubscribeAll = new Subject();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------------
|
|
// @ Lifecycle hooks
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* On init
|
|
*/
|
|
ngOnInit(): void
|
|
{
|
|
// Listen for router events
|
|
this._router.events
|
|
.pipe(
|
|
filter(event => event instanceof NavigationEnd),
|
|
takeUntil(this._unsubscribeAll)
|
|
)
|
|
.subscribe((event: NavigationEnd) => {
|
|
|
|
// Check if the url can be found in
|
|
// one of the children of this item
|
|
if ( this.isUrlInChildren(this.item, event.urlAfterRedirects) )
|
|
{
|
|
this.expand();
|
|
}
|
|
else
|
|
{
|
|
this.collapse();
|
|
}
|
|
});
|
|
|
|
// Listen for collapsing of any navigation item
|
|
this._fuseNavigationService.onItemCollapsed
|
|
.pipe(takeUntil(this._unsubscribeAll))
|
|
.subscribe(
|
|
(clickedItem) => {
|
|
if ( clickedItem && clickedItem.children )
|
|
{
|
|
// Check if the clicked item is one
|
|
// of the children of this item
|
|
if ( this.isChildrenOf(this.item, clickedItem) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Check if the url can be found in
|
|
// one of the children of this item
|
|
if ( this.isUrlInChildren(this.item, this._router.url) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// If the clicked item is not this item, collapse...
|
|
if ( this.item !== clickedItem )
|
|
{
|
|
this.collapse();
|
|
}
|
|
}
|
|
}
|
|
);
|
|
|
|
// Check if the url can be found in
|
|
// one of the children of this item
|
|
if ( this.isUrlInChildren(this.item, this._router.url) )
|
|
{
|
|
this.expand();
|
|
}
|
|
else
|
|
{
|
|
this.collapse();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* On destroy
|
|
*/
|
|
ngOnDestroy(): void
|
|
{
|
|
// Unsubscribe from all subscriptions
|
|
this._unsubscribeAll.next();
|
|
this._unsubscribeAll.complete();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------------
|
|
// @ Public methods
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Toggle collapse
|
|
*
|
|
* @param ev
|
|
*/
|
|
toggleOpen(ev): void
|
|
{
|
|
ev.preventDefault();
|
|
|
|
this.isOpen = !this.isOpen;
|
|
|
|
// Navigation collapse toggled...
|
|
this._fuseNavigationService.onItemCollapsed.next(this.item);
|
|
this._fuseNavigationService.onItemCollapseToggled.next();
|
|
}
|
|
|
|
/**
|
|
* Expand the collapsable navigation
|
|
*/
|
|
expand(): void
|
|
{
|
|
if ( this.isOpen )
|
|
{
|
|
return;
|
|
}
|
|
|
|
this.isOpen = true;
|
|
this._fuseNavigationService.onItemCollapseToggled.next();
|
|
}
|
|
|
|
/**
|
|
* Collapse the collapsable navigation
|
|
*/
|
|
collapse(): void
|
|
{
|
|
if ( !this.isOpen )
|
|
{
|
|
return;
|
|
}
|
|
|
|
this.isOpen = false;
|
|
this._fuseNavigationService.onItemCollapseToggled.next();
|
|
}
|
|
|
|
/**
|
|
* Check if the given parent has the
|
|
* given item in one of its children
|
|
*
|
|
* @param parent
|
|
* @param item
|
|
* @returns {boolean}
|
|
*/
|
|
isChildrenOf(parent, item): boolean
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if the given url can be found
|
|
* in one of the given parent's children
|
|
*
|
|
* @param parent
|
|
* @param url
|
|
* @returns {boolean}
|
|
*/
|
|
isUrlInChildren(parent, url): boolean
|
|
{
|
|
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;
|
|
}
|
|
|
|
}
|