diff --git a/src/@fuse/components/navigation/navigation.service.ts b/src/@fuse/components/navigation/navigation.service.ts index 677c5ca3..490f895c 100644 --- a/src/@fuse/components/navigation/navigation.service.ts +++ b/src/@fuse/components/navigation/navigation.service.ts @@ -1,25 +1,139 @@ import { Injectable } from '@angular/core'; -import { Subject } from 'rxjs'; +import { BehaviorSubject, Observable, Subject } from 'rxjs'; @Injectable() export class FuseNavigationService { flatNavigation: any[] = []; - onItemCollapsed: Subject = new Subject; - onItemCollapseToggled: Subject = new Subject; + onItemCollapsed: Subject; + onItemCollapseToggled: Subject; + + // Private + private _onNavigationChanged: BehaviorSubject; + private _onNavigationRegistered: BehaviorSubject; + private _onNavigationUnregistered: BehaviorSubject; + + private _currentNavigationKey: string; + private _registry: { [key: string]: any } = {}; /** * Constructor */ constructor() { + // Set the defaults + this.onItemCollapsed = new Subject(); + this.onItemCollapseToggled = new Subject(); + + // Set the private defaults + this._currentNavigationKey = null; + this._onNavigationChanged = new BehaviorSubject(null); + this._onNavigationRegistered = new BehaviorSubject(null); + this._onNavigationUnregistered = new BehaviorSubject(null); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + + /** + * Get onNavigationChanged + * + * @returns {Observable} + */ + get onNavigationChanged(): Observable + { + return this._onNavigationChanged.asObservable(); + } + + /** + * Get onNavigationRegistered + * + * @returns {Observable} + */ + get onNavigationRegistered(): Observable + { + return this._onNavigationRegistered.asObservable(); + } + + /** + * Get onNavigationUnregistered + * + * @returns {Observable} + */ + get onNavigationUnregistered(): Observable + { + return this._onNavigationUnregistered.asObservable(); } // ----------------------------------------------------------------------------------------------------- // @ Public methods // ----------------------------------------------------------------------------------------------------- + /** + * Register the given navigation + * with the given key + * + * @param key + * @param navigation + */ + register(key, navigation): void + { + // Check if the key already being used + if ( this._registry[key] ) + { + console.error(`The navigation with the key '${key}' already exists. Either unregister it first or use a unique key.`); + + return; + } + + // Add to the registry + this._registry[key] = navigation; + + // Notify the subject + this._onNavigationRegistered.next([key, navigation]); + } + + /** + * Unregister the navigation from the registry + * @param key + */ + unregister(key): void + { + // Check if the navigation exists + if ( !this._registry[key] ) + { + console.warn(`The navigation with the key '${key}' doesn't exist in the registry.`); + } + + // Unregister the sidebar + delete this._registry[key]; + + // Notify the subject + this._onNavigationUnregistered.next(key); + } + + /** + * Get navigation from registry by key + * + * @param key + * @returns {any} + */ + getNavigation(key): any + { + // Check if the navigation exists + if ( !this._registry[key] ) + { + console.warn(`The navigation with the key '${key}' doesn't exist in the registry.`); + + return; + } + + // Return the sidebar + return this._registry[key]; + } + /** * Get flattened navigation array * @@ -33,10 +147,15 @@ export class FuseNavigationService if ( navItem.type === 'item' ) { this.flatNavigation.push({ - title: navItem.title, - type : navItem.type, - icon : navItem.icon || false, - url : navItem.url + id : navItem.id || null, + title : navItem.title || null, + translate : navItem.translate || null, + type : navItem.type, + icon : navItem.icon || null, + url : navItem.url || null, + function : navItem.function || null, + exactMatch: navItem.exactMatch || false, + badge : navItem.badge || null }); continue; @@ -53,4 +172,117 @@ export class FuseNavigationService return this.flatNavigation; } + + /** + * Get the current navigation + * + * @returns {any} + */ + getCurrentNavigation(): any + { + if ( !this._currentNavigationKey ) + { + console.warn(`The current navigation is not set.`); + + return; + } + + return this.getNavigation(this._currentNavigationKey); + } + + /** + * Set the navigation with the key + * as the current navigation + * + * @param key + */ + setCurrentNavigation(key): void + { + // Check if the sidebar exists + if ( !this._registry[key] ) + { + console.warn(`The navigation with the key '${key}' doesn't exist in the registry.`); + + return; + } + + // Set the current navigation key + this._currentNavigationKey = key; + + // Notify the subject + this._onNavigationChanged.next(key); + } + + /** + * Get navigation item by id from the + * current navigation + * + * @param id + * @param {any} navigation + * @returns {any | boolean} + */ + getNavigationItem(id, navigation = null): any | boolean + { + if ( !navigation ) + { + navigation = this.getCurrentNavigation(); + } + + for ( const item of navigation ) + { + if ( item.id === id ) + { + return item; + } + + if ( item.children ) + { + this.getNavigationItem(id, item.children); + } + } + + return false; + } + + /** + * Add a navigation item to the specified location + * + * @param item + * @param id + */ + addNavigationItem(item, id): void + { + // Get the current navigation + const navigation: any[] = this.getCurrentNavigation(); + + // Add to the end of the navigation + if ( id === 'end' ) + { + navigation.push(item); + + return; + } + + // Add to the start of the navigation + if ( id === 'start' ) + { + navigation.unshift(item); + } + + // Add it to a specific location + const parent: any = this.getNavigationItem(id); + + if ( parent ) + { + // Check if parent has a children entry, + // and add it if it doesn't + if ( !parent.children ) + { + parent.children = []; + } + + // Add the item + parent.children.push(item); + } + } }