[Dashboard]: Reworked sidebar menu auto expanding
[src/xds/xds-agent.git] / webapp / src / app / @theme / layouts / xds / xds.layout.ts
index 8987584..b362fff 100644 (file)
@@ -1,4 +1,4 @@
-import { Component, OnDestroy } from '@angular/core';
+import { Component, OnDestroy, EventEmitter } from '@angular/core';
 import {
   NbMediaBreakpoint,
   NbMediaBreakpointsService,
@@ -11,8 +11,11 @@ import {
 import { StateService } from '../../../@core/data/state.service';
 
 import { Subscription } from 'rxjs/Subscription';
+import { Observable } from 'rxjs/Observable';
 import 'rxjs/add/operator/withLatestFrom';
 import 'rxjs/add/operator/delay';
+import 'rxjs/add/observable/of';
+import 'rxjs/add/operator/takeUntil';
 
 // TODO: move layouts into the framework
 @Component({
@@ -26,17 +29,22 @@ export class XdsLayoutComponent implements OnDestroy {
   subMenu: NbMenuItem[] = [];
   layout: any = {};
   sidebar: any = {};
+  sidebarPinned = false;
   sidebarCompact = true;
 
   protected layoutState$: Subscription;
   protected sidebarState$: Subscription;
   protected menuClick$: Subscription;
 
+  private _mouseEnterStream: EventEmitter<any> = new EventEmitter();
+  private _mouseLeaveStream: EventEmitter<any> = new EventEmitter();
+
   constructor(protected stateService: StateService,
     protected menuService: NbMenuService,
     protected themeService: NbThemeService,
     protected bpService: NbMediaBreakpointsService,
     protected sidebarService: NbSidebarService) {
+
     this.layoutState$ = this.stateService.onLayoutState()
       .subscribe((layout: string) => this.layout = layout);
 
@@ -46,26 +54,61 @@ export class XdsLayoutComponent implements OnDestroy {
       });
 
     const isBp = this.bpService.getByName('is');
+
     this.menuClick$ = this.menuService.onItemSelect()
       .withLatestFrom(this.themeService.onMediaQueryChange())
       .delay(20)
       .subscribe(([item, [bpFrom, bpTo]]: [any, [NbMediaBreakpoint, NbMediaBreakpoint]]) => {
-
+        /*
         this.sidebarCompact = false;
+        */
+        // automatically collapse sidebar for narrow screen / mobile
         if (bpTo.width <= isBp.width) {
           this.sidebarService.collapse('menu-sidebar');
         }
       });
 
     // Set sidebarCompact according to sidebar state changes
-    this.sidebarService.onToggle().subscribe(s => s.tag === 'menu-sidebar' && (this.sidebarCompact = !this.sidebarCompact));
+    this.sidebarService.onToggle().subscribe(s => {
+      if (s.tag === 'menu-sidebar') {
+        this.sidebarPinned = false;
+        this.sidebarCompact = !this.sidebarCompact;
+      }
+    });
+
     this.sidebarService.onCollapse().subscribe(s => s.tag === 'menu-sidebar' && (this.sidebarCompact = true));
-    this.sidebarService.onExpand().subscribe(() => this.sidebarCompact = false);
+    this.sidebarService.onExpand().subscribe(s => s.tag === 'menu-sidebar' && (this.sidebarCompact = false));
     this.menuService.onSubmenuToggle().subscribe(i => i.item && i.item.expanded && (this.sidebarCompact = false));
-  }
 
-  toogleSidebar() {
-    this.sidebarService.toggle(true, 'menu-sidebar');
+    // Automatically expand sidebar on mouse over
+    this._mouseEnterStream.flatMap(e => {
+      return Observable
+        .of(e)
+        .delay(100)
+        .takeUntil(this._mouseLeaveStream);
+    })
+      .subscribe(e => {
+        if (this.sidebarPinned || !this.sidebarCompact) {
+          return;
+        }
+        // this._mouseLeaveStream.emit(null);
+        this.sidebarService.toggle(false, 'menu-sidebar');
+      });
+
+    // Automatically collapse sidebar on mouse leave
+    this._mouseLeaveStream.flatMap(e => {
+      return Observable
+        .of(e)
+        .delay(100)
+        .takeUntil(this._mouseEnterStream);
+    })
+      .subscribe(e => {
+        if (this.sidebarPinned || this.sidebarCompact) {
+          return;
+        }
+        // this._mouseEnterStream.emit(null);
+        this.sidebarService.toggle(true, 'menu-sidebar');
+      });
   }
 
   ngOnDestroy() {
@@ -73,4 +116,16 @@ export class XdsLayoutComponent implements OnDestroy {
     this.sidebarState$.unsubscribe();
     this.menuClick$.unsubscribe();
   }
+
+  onMouseEnter($event) {
+    this._mouseEnterStream.emit($event);
+  }
+
+  onMouseLeave($event) {
+    this._mouseLeaveStream.emit($event);
+  }
+
+  pinSidebar() {
+    this.sidebarPinned = !this.sidebarPinned;
+  }
 }