diff --git a/src/@fuse/components/navigation/navigation.component.ts b/src/@fuse/components/navigation/navigation.component.ts index 36f6b0f4..6e645df6 100644 --- a/src/@fuse/components/navigation/navigation.component.ts +++ b/src/@fuse/components/navigation/navigation.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @@ -8,7 +8,8 @@ import { FuseNavigationService } from '@fuse/components/navigation/navigation.se selector : 'fuse-navigation', templateUrl : './navigation.component.html', styleUrls : ['./navigation.component.scss'], - encapsulation: ViewEncapsulation.None + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush }) export class FuseNavigationComponent implements OnInit { @@ -22,9 +23,12 @@ export class FuseNavigationComponent implements OnInit private _unsubscribeAll: Subject; /** - * Constructor + * + * @param {ChangeDetectorRef} _changeDetectorRef + * @param {FuseNavigationService} _fuseNavigationService */ constructor( + private _changeDetectorRef: ChangeDetectorRef, private _fuseNavigationService: FuseNavigationService ) { @@ -48,7 +52,39 @@ export class FuseNavigationComponent implements OnInit this._fuseNavigationService.onNavigationChanged .pipe(takeUntil(this._unsubscribeAll)) .subscribe(() => { + + // Load the navigation this.navigation = this._fuseNavigationService.getCurrentNavigation(); + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Subscribe to navigation item additions + this._fuseNavigationService.onNavigationItemAdded + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Subscribe to navigation item updates + this._fuseNavigationService.onNavigationItemUpdated + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Subscribe to navigation item removal + this._fuseNavigationService.onNavigationItemRemoved + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + + // Mark for check + this._changeDetectorRef.markForCheck(); }); } } diff --git a/src/@fuse/components/navigation/navigation.service.ts b/src/@fuse/components/navigation/navigation.service.ts index 3b07b456..14346c02 100644 --- a/src/@fuse/components/navigation/navigation.service.ts +++ b/src/@fuse/components/navigation/navigation.service.ts @@ -1,5 +1,6 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable, Subject } from 'rxjs'; +import * as _ from 'lodash'; import { FuseNavigationItem } from '@fuse/types'; @@ -15,6 +16,9 @@ export class FuseNavigationService private _onNavigationChanged: BehaviorSubject; private _onNavigationRegistered: BehaviorSubject; private _onNavigationUnregistered: BehaviorSubject; + private _onNavigationItemAdded: BehaviorSubject; + private _onNavigationItemUpdated: BehaviorSubject; + private _onNavigationItemRemoved: BehaviorSubject; private _currentNavigationKey: string; private _registry: { [key: string]: any } = {}; @@ -33,6 +37,9 @@ export class FuseNavigationService this._onNavigationChanged = new BehaviorSubject(null); this._onNavigationRegistered = new BehaviorSubject(null); this._onNavigationUnregistered = new BehaviorSubject(null); + this._onNavigationItemAdded = new BehaviorSubject(null); + this._onNavigationItemUpdated = new BehaviorSubject(null); + this._onNavigationItemRemoved = new BehaviorSubject(null); } // ----------------------------------------------------------------------------------------------------- @@ -69,6 +76,36 @@ export class FuseNavigationService return this._onNavigationUnregistered.asObservable(); } + /** + * Get onNavigationItemAdded + * + * @returns {Observable} + */ + get onNavigationItemAdded(): Observable + { + return this._onNavigationItemAdded.asObservable(); + } + + /** + * Get onNavigationItemUpdated + * + * @returns {Observable} + */ + get onNavigationItemUpdated(): Observable + { + return this._onNavigationItemUpdated.asObservable(); + } + + /** + * Get onNavigationItemRemoved + * + * @returns {Observable} + */ + get onNavigationItemRemoved(): Observable + { + return this._onNavigationItemRemoved.asObservable(); + } + // ----------------------------------------------------------------------------------------------------- // @ Public methods // ----------------------------------------------------------------------------------------------------- @@ -319,6 +356,33 @@ export class FuseNavigationService // Add the item parent.children.push(item); } + + // Trigger the observable + this._onNavigationItemAdded.next(true); + } + + /** + * Update navigation item with the given id + * + * @param id + * @param properties + */ + updateNavigationItem(id, properties): void + { + // Get the navigation item + const navigationItem = this.getNavigationItem(id); + + // If there is no navigation with the give id, return + if ( !navigationItem ) + { + return; + } + + // Merge the navigation properties + _.merge(navigationItem, properties); + + // Trigger the observable + this._onNavigationItemUpdated.next(true); } /** @@ -346,5 +410,8 @@ export class FuseNavigationService // Remove the item parent.splice(parent.indexOf(item), 1); + + // Trigger the observable + this._onNavigationItemRemoved.next(true); } } diff --git a/src/@fuse/components/navigation/vertical/collapsable/collapsable.component.ts b/src/@fuse/components/navigation/vertical/collapsable/collapsable.component.ts index fbda7a18..67ca4cf6 100644 --- a/src/@fuse/components/navigation/vertical/collapsable/collapsable.component.ts +++ b/src/@fuse/components/navigation/vertical/collapsable/collapsable.component.ts @@ -1,4 +1,4 @@ -import { Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core'; +import { ChangeDetectorRef, Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core'; import { NavigationEnd, Router } from '@angular/router'; import { Subject } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; @@ -30,10 +30,12 @@ export class FuseNavVerticalCollapsableComponent implements OnInit, OnDestroy /** * Constructor * + * @param {ChangeDetectorRef} _changeDetectorRef * @param {FuseNavigationService} _fuseNavigationService * @param {Router} _router */ constructor( + private _changeDetectorRef: ChangeDetectorRef, private _fuseNavigationService: FuseNavigationService, private _router: Router ) @@ -111,6 +113,33 @@ export class FuseNavVerticalCollapsableComponent implements OnInit, OnDestroy { this.collapse(); } + + // Subscribe to navigation item additions + this._fuseNavigationService.onNavigationItemAdded + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Subscribe to navigation item updates + this._fuseNavigationService.onNavigationItemUpdated + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Subscribe to navigation item removal + this._fuseNavigationService.onNavigationItemRemoved + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); } /** @@ -154,6 +183,10 @@ export class FuseNavVerticalCollapsableComponent implements OnInit, OnDestroy } this.isOpen = true; + + // Mark for check + this._changeDetectorRef.markForCheck(); + this._fuseNavigationService.onItemCollapseToggled.next(); } @@ -168,6 +201,10 @@ export class FuseNavVerticalCollapsableComponent implements OnInit, OnDestroy } this.isOpen = false; + + // Mark for check + this._changeDetectorRef.markForCheck(); + this._fuseNavigationService.onItemCollapseToggled.next(); } diff --git a/src/@fuse/components/navigation/vertical/group/group.component.ts b/src/@fuse/components/navigation/vertical/group/group.component.ts index d43e223e..58e5bbca 100644 --- a/src/@fuse/components/navigation/vertical/group/group.component.ts +++ b/src/@fuse/components/navigation/vertical/group/group.component.ts @@ -1,13 +1,16 @@ -import { Component, HostBinding, Input } from '@angular/core'; +import { ChangeDetectorRef, Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FuseNavigationItem } from '@fuse/types'; +import { FuseNavigationService } from '@fuse/components/navigation/navigation.service'; @Component({ selector : 'fuse-nav-vertical-group', templateUrl: './group.component.html', styleUrls : ['./group.component.scss'] }) -export class FuseNavVerticalGroupComponent +export class FuseNavVerticalGroupComponent implements OnInit, OnDestroy { @HostBinding('class') classes = 'nav-group nav-item'; @@ -15,11 +18,72 @@ export class FuseNavVerticalGroupComponent @Input() item: FuseNavigationItem; + // Private + private _unsubscribeAll: Subject; + /** * Constructor */ - constructor() + + /** + * + * @param {ChangeDetectorRef} _changeDetectorRef + * @param {FuseNavigationService} _fuseNavigationService + */ + constructor( + private _changeDetectorRef: ChangeDetectorRef, + private _fuseNavigationService: FuseNavigationService + ) { + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Subscribe to navigation item additions + this._fuseNavigationService.onNavigationItemAdded + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Subscribe to navigation item updates + this._fuseNavigationService.onNavigationItemUpdated + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Subscribe to navigation item removal + this._fuseNavigationService.onNavigationItemRemoved + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } } diff --git a/src/@fuse/components/navigation/vertical/item/item.component.ts b/src/@fuse/components/navigation/vertical/item/item.component.ts index c807e381..b23ecc1c 100644 --- a/src/@fuse/components/navigation/vertical/item/item.component.ts +++ b/src/@fuse/components/navigation/vertical/item/item.component.ts @@ -1,13 +1,16 @@ -import { Component, HostBinding, Input } from '@angular/core'; +import { ChangeDetectorRef, Component, HostBinding, Input, OnDestroy, OnInit } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { FuseNavigationItem } from '@fuse/types'; +import { FuseNavigationService } from '@fuse/components/navigation/navigation.service'; @Component({ selector : 'fuse-nav-vertical-item', templateUrl: './item.component.html', styleUrls : ['./item.component.scss'] }) -export class FuseNavVerticalItemComponent +export class FuseNavVerticalItemComponent implements OnInit, OnDestroy { @HostBinding('class') classes = 'nav-item'; @@ -15,10 +18,71 @@ export class FuseNavVerticalItemComponent @Input() item: FuseNavigationItem; + // Private + private _unsubscribeAll: Subject; + /** * Constructor */ - constructor() + + /** + * + * @param {ChangeDetectorRef} _changeDetectorRef + * @param {FuseNavigationService} _fuseNavigationService + */ + constructor( + private _changeDetectorRef: ChangeDetectorRef, + private _fuseNavigationService: FuseNavigationService + ) { + // Set the private defaults + this._unsubscribeAll = new Subject(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void + { + // Subscribe to navigation item additions + this._fuseNavigationService.onNavigationItemAdded + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Subscribe to navigation item updates + this._fuseNavigationService.onNavigationItemUpdated + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Subscribe to navigation item removal + this._fuseNavigationService.onNavigationItemRemoved + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + } + + /** + * On destroy + */ + ngOnDestroy(): void + { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(); + this._unsubscribeAll.complete(); } } diff --git a/src/app/main/documentation/components/navigation/navigation.component.html b/src/app/main/documentation/components/navigation/navigation.component.html index 18b215a7..af951206 100644 --- a/src/app/main/documentation/components/navigation/navigation.component.html +++ b/src/app/main/documentation/components/navigation/navigation.component.html @@ -3,7 +3,7 @@
-
+
home chevron_right Documentation @@ -187,12 +187,13 @@ showHideCalendarMenuItem(): void { - // Get the calendar item from the navigation - const calendarNavItem = this._fuseNavigationService.getNavigationItem('calendar'); - // Toggle the visibility this.hidden = !this.hidden; - calendarNavItem.hidden = this.hidden; + + // Update the calendar menu item + this._fuseNavigationService.updateNavigationItem('calendar', { + hidden: this.hidden + }); } @@ -211,11 +212,12 @@ @@ -242,14 +244,12 @@ url : '/apps/calendar' }; - // Get the calendar item from the navigation - const calendarNavItem = this._fuseNavigationService.getNavigationItem('calendar'); - - // Make the calendar navigation item collapsable - calendarNavItem.type = 'collapse'; - - // Add the navigation item - this._fuseNavigationService.addNavigationItem(newNavItem, 'calendar'); + this._fuseNavigationService.updateNavigationItem('calendar', { + type: 'collapsable', + children: [ + newNavItem + ] + }); } diff --git a/src/app/main/documentation/components/navigation/navigation.component.ts b/src/app/main/documentation/components/navigation/navigation.component.ts index 8b58a1ea..e661c110 100644 --- a/src/app/main/documentation/components/navigation/navigation.component.ts +++ b/src/app/main/documentation/components/navigation/navigation.component.ts @@ -32,12 +32,13 @@ export class DocsComponentsNavigationComponent */ showHideCalendarMenuItem(): void { - // Get the calendar item from the navigation - const calendarNavItem = this._fuseNavigationService.getNavigationItem('calendar'); - // Toggle the visibility this.hidden = !this.hidden; - calendarNavItem.hidden = this.hidden; + + // Update the calendar menu item + this._fuseNavigationService.updateNavigationItem('calendar', { + hidden: this.hidden + }); } /** @@ -45,11 +46,10 @@ export class DocsComponentsNavigationComponent */ updateMailBadge(): void { - // Get the mail nav item - const mailNavItem = this._fuseNavigationService.getNavigationItem('mail'); - // Update the badge title - mailNavItem.badge.title = 35; + this._fuseNavigationService.updateNavigationItem('02001', { + title: 'Transactionssss' + }); } /** @@ -65,14 +65,12 @@ export class DocsComponentsNavigationComponent url : '/apps/calendar' }; - // Get the calendar item from the navigation - const calendarNavItem = this._fuseNavigationService.getNavigationItem('calendar'); - - // Make the calendar navigation item collapsable - calendarNavItem.type = 'collapsable'; - - // Add the navigation item - this._fuseNavigationService.addNavigationItem(newNavItem, 'calendar'); + this._fuseNavigationService.updateNavigationItem('calendar', { + type: 'collapsable', + children: [ + newNavItem + ] + }); } /**