Browse Source

sidemenu: responsive sidemenu view for smallest breakpoint

For the smallest breakpoint, expands the sidemenu to be width 100% and
to be toggled on or off rather than visible all the time.
Daniel Lee 8 years ago
parent
commit
66657d24b8

+ 10 - 0
public/app/core/components/grafana_app.ts

@@ -85,6 +85,16 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
         }
       });
 
+      let sidemenuOpenSmallBreakpoint = scope.contextSrv.sidemenuSmallBreakpoint;
+      body.toggleClass('sidemenu-open--xs', sidemenuOpenSmallBreakpoint);
+
+      scope.$watch('contextSrv.sidemenuSmallBreakpoint', newVal => {
+        if (sidemenuOpenSmallBreakpoint !== scope.contextSrv.sidemenuSmallBreakpoint) {
+          sidemenuOpenSmallBreakpoint = scope.contextSrv.sidemenuSmallBreakpoint;
+          body.toggleClass('sidemenu-open--xs', scope.contextSrv.sidemenuSmallBreakpoint);
+        }
+      });
+
       // tooltip removal fix
       // manage page classes
       var pageClass;

+ 6 - 0
public/app/core/components/sidemenu/sidemenu.html

@@ -2,6 +2,12 @@
 	<img src="public/img/grafana_icon.svg"></img>
 </a>
 
+<a class="sidemenu__logo_small_breakpoint" ng-click="ctrl.toggleSideMenuSmallBreakpoint()">
+  <img src="public/img/grafana_icon.svg"></img>
+  <p class="sidemenu__close"><i class="fa fa-times"></i>&nbsp;Close</p>
+</a>
+
+
 <div class="sidemenu__top">
 	<div ng-repeat="item in ::ctrl.mainLinks" class="sidemenu-item dropdown">
 		<a href="{{::item.url}}" class="sidemenu-link" target="{{::item.target}}">

+ 10 - 0
public/app/core/components/sidemenu/sidemenu.ts

@@ -11,6 +11,7 @@ export class SideMenuCtrl {
   bottomNav: any;
   loginUrl: string;
   isSignedIn: boolean;
+  smallBPSideMenuOpen = false;
 
   /** @ngInject */
   constructor(private $scope, private $rootScope, private $location, private contextSrv, private $timeout) {
@@ -28,6 +29,10 @@ export class SideMenuCtrl {
     }
 
     this.$scope.$on('$routeChangeSuccess', () => {
+      if (this.smallBPSideMenuOpen) {
+        this.contextSrv.setSideMenuForSmallBreakpoint(false, true);
+        this.smallBPSideMenuOpen = false;
+      }
       this.loginUrl = 'login?redirect=' + encodeURIComponent(this.$location.path());
     });
   }
@@ -39,6 +44,11 @@ export class SideMenuCtrl {
     });
   }
 
+  toggleSideMenuSmallBreakpoint() {
+    this.smallBPSideMenuOpen = !this.smallBPSideMenuOpen;
+    this.contextSrv.setSideMenuForSmallBreakpoint(this.smallBPSideMenuOpen, false);
+  }
+
   switchOrg() {
     this.$rootScope.appEvent('show-modal', {
       templateHtml: '<org-switcher dismiss="dismiss()"></org-switcher>',

+ 7 - 2
public/app/core/services/context_srv.ts

@@ -27,9 +27,10 @@ export class ContextSrv {
   isGrafanaAdmin: any;
   isEditor: any;
   sidemenu: any;
+  sidemenuSmallBreakpoint = false;
 
   constructor() {
-    this.sidemenu = store.getBool('grafana.sidemenu', false);
+    this.sidemenu = store.getBool('grafana.sidemenu', true);
 
     if (!config.buildInfo) {
       config.buildInfo = {};
@@ -55,7 +56,11 @@ export class ContextSrv {
 
   toggleSideMenu() {
     this.sidemenu = !this.sidemenu;
-    store.set('grafana.sidemenu',this.sidemenu);
+    store.set('grafana.sidemenu', this.sidemenu);
+  }
+
+  setSideMenuForSmallBreakpoint(show: boolean, persistToggle: boolean) {
+    this.sidemenuSmallBreakpoint = show;
   }
 }
 

+ 120 - 28
public/sass/components/_sidemenu.scss

@@ -4,25 +4,34 @@
   flex-flow: column;
   flex-direction: column;
   width: $side-menu-width;
-  background: $navbarBackground;
   z-index: $zindex-sidemenu;
   a:focus {
     text-decoration: none;
   }
-}
 
-.sidemenu-open {
-  .sidemenu {
-    background: $side-menu-bg;
-    position: initial;
-    height: auto;
-    box-shadow: $side-menu-shadow;
-    position: relative;
-    z-index: $zindex-sidemenu;
+  .sidemenu__logo_small_breakpoint {
+    display: none;
   }
-  .sidemenu__top,
-  .sidemenu__bottom {
-    display: block;
+
+  .sidemenu__close {
+    display: none;
+  }
+}
+
+@include media-breakpoint-up(sm) {
+  .sidemenu-open {
+    .sidemenu {
+      background: $side-menu-bg;
+      position: initial;
+      height: auto;
+      box-shadow: $side-menu-shadow;
+      position: relative;
+      z-index: $zindex-sidemenu;
+    }
+    .sidemenu__top,
+    .sidemenu__bottom {
+      display: block;
+    }
   }
 }
 
@@ -41,21 +50,23 @@
   position: relative;
   @include left-brand-border();
 
-  &.active,
-  &:hover {
-    background-color: $side-menu-item-hover-bg;
-    @include left-brand-border-gradient();
+  @include media-breakpoint-up(sm) {
+    &.active,
+    &:hover {
+      background-color: $side-menu-item-hover-bg;
+      @include left-brand-border-gradient();
 
-    .dropdown-menu {
-      margin: 0;
-      display: block;
-      opacity: 0;
-      top: 0px;
-      // important to overlap it otherwise it can be hidden
-      // again by the mouse getting outside the hover space
-      left: $side-menu-width - 2px;
-      @include animation('dropdown-anim 150ms ease-in-out 100ms forwards');
-      z-index: $zindex-sidemenu;
+      .dropdown-menu {
+        margin: 0;
+        display: block;
+        opacity: 0;
+        top: 0px;
+        // important to overlap it otherwise it can be hidden
+        // again by the mouse getting outside the hover space
+        left: $side-menu-width - 2px;
+        @include animation('dropdown-anim 150ms ease-in-out 100ms forwards');
+        z-index:  $zindex-sidemenu;
+      }
     }
   }
 }
@@ -152,7 +163,7 @@ li.sidemenu-org-switcher {
   }
 }
 
-.sidemenu__logo {
+.sidemenu__logo, .sidemenu__logo_small_breakpoint {
   display: block;
   padding: 0.4rem 1.0rem 0.4rem 0.65rem;
   min-height: $navbarHeight;
@@ -170,3 +181,84 @@ li.sidemenu-org-switcher {
   }
 }
 
+@include media-breakpoint-down(xs) {
+  .sidemenu-open {
+    .navbar {
+      padding-left: 60px !important;
+    }
+  }
+
+  .sidemenu-open--xs {
+    .sidemenu {
+      width: 100%;
+      background: $side-menu-bg;
+      position: initial;
+      height: auto;
+      box-shadow: $side-menu-shadow;
+      position: relative;
+      z-index: $zindex-sidemenu;
+    }
+
+    .sidemenu__close {
+      display: block;
+      font-size: $font-size-md;
+    }
+
+    .sidemenu__top,
+    .sidemenu__bottom {
+      display: block;
+    }
+  }
+
+  .sidemenu {
+    .sidemenu__logo {
+      display: none;
+    }
+    .sidemenu__logo_small_breakpoint {
+      display: flex;
+      flex-direction: row;
+      justify-content: space-between;
+      align-items: baseline;
+
+      &:hover {
+        background: transparent;
+      }
+    }
+
+    .sidemenu__top {
+      padding-top: 0rem;
+    }
+
+    .side-menu-header {
+      padding-left: 10px;
+    }
+
+    .sidemenu-link {
+      text-align: left;
+    }
+
+    .sidemenu-icon {
+      display: none
+    }
+
+    .dropdown-menu--sidemenu {
+      display: block;
+      position: unset;
+      width: 100%;
+      float: none;
+      margin-top: 0.5rem;
+      margin-bottom: 0.5rem;
+
+      > li > a {
+        padding-left: 15px;
+      }
+    }
+
+    .sidemenu__bottom {
+      .dropdown-menu--sidemenu {
+        display: flex;
+        flex-direction: column-reverse;
+      }
+    }
+  }
+}