Secondary Submenu

Added a secondary menu that extends out from the sidebar, to indicate
that there are additional options to choose from. In this case,
I've implemented it on the admin menu so that we have room to add
team administration.

Change-Id: Ie7aa392e172bafc790ed2d28d831171a60be8467
This commit is contained in:
Michael Krotscheck 2014-07-23 16:59:45 -07:00
parent a0cc35c72f
commit 8cf3d9ff4f
9 changed files with 256 additions and 9 deletions

View File

@ -29,7 +29,14 @@ angular.module('sb.admin', [ 'sb.services', 'sb.templates', 'sb.util',
$stateProvider
.state('admin', {
abstract: true,
template: '<div ui-view></div>',
views: {
'submenu@': {
templateUrl: 'app/admin/template/admin_submenu.html'
},
'@': {
template: '<div ui-view></div>'
}
},
url: '/admin',
resolve: {
isSuperuser: PermissionResolver

View File

@ -0,0 +1,22 @@
<!--
~ Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
~
~ Licensed under the Apache License, Version 2.0 (the "License"); you may
~ not use this file except in compliance with the License. You may obtain
~ a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
~ License for the specific language governing permissions and limitations
~ under the License.
-->
<ul class="nav nav-pills nav-stacked text-center">
<li active-path="^\/admin/project_group.*">
<a href="#!/admin/project_group" title="Project Groups">
<i class="fa fa-sb-project-group fa-lg"></i>
</a>
</li>
</ul>

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
/**
* Application controller, which keeps track of our active state chain and
* sets global scope variable accordingly.
*/
angular.module('storyboard').controller('ApplicationController',
function ($scope, $state, $rootScope) {
'use strict';
/**
* This method traverses the current active state tree to see if the
* current state, or any of its parents, have a submenu declared.
*
* @param state
*/
function hasSubmenu(state) {
for (var stateName in state.views) {
if (!!stateName.match(/^submenu@/)) {
return true;
}
}
if (!!state.parent) {
return hasSubmenu(state.parent);
} else {
return false;
}
}
/**
* Listen to changes in the state machine to trigger our submenu
* scan.
*/
$rootScope.$on('$stateChangeSuccess',
function () {
$scope.hasSubmenu = hasSubmenu($state.$current);
});
// Set a sane default.
$scope.hasSubmenu = false;
});

View File

@ -17,8 +17,8 @@
<nav class="navbar navbar-inverse navbar-fixed-side
navbar-fixed-side-header-offset"
role="navigation"
ng-controller="HeaderController">
<div class="container-fluid">
ng-class="{'navbar-fixed-side-has-submenu': hasSubmenu}">
<div class="nav-main">
<ul class="nav nav-pills nav-stacked text-center">
<li active-path="^\/search.*">
<a href="#!/search">
@ -73,6 +73,8 @@
</a>
</li>
</ul>
</div>
<div ui-view="submenu"
class="nav-submenu">
</div>
</nav>

View File

@ -44,7 +44,8 @@
<script src="js/storyboard.js"></script>
<script src="js/templates.js"></script>
</head>
<body ng-class="{'logged-in' : isLoggedIn}">
<body ng-class="{'logged-in' : isLoggedIn, 'submenu': hasSubmenu}"
ng-controller="ApplicationController">
<header ng-include src="'app/storyboard/template/header_menu.html'"></header>
<div ng-include src="'app/storyboard/template/side_menu.html'"></div>

View File

@ -24,23 +24,39 @@ body {
@media (max-width: @screen-xs-max) {
body {
margin-right: @navbar-fixed-side-width-xs;
&.submenu {
margin-right: (@navbar-fixed-side-width-xs + @navbar-fixed-side-submenu-width-xs);
}
}
}
@media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
body {
margin-left: @navbar-fixed-side-width-sm;
&.submenu {
margin-left: (@navbar-fixed-side-width-sm + @navbar-fixed-side-submenu-width-sm);
}
}
}
@media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
body {
margin-left: @navbar-fixed-side-width-md;
&.submenu {
margin-left: (@navbar-fixed-side-width-md + @navbar-fixed-side-submenu-width-md);
}
}
}
@media (min-width: @screen-lg-min) {
body {
margin-left: @navbar-fixed-side-width-lg;
&.submenu {
margin-left: (@navbar-fixed-side-width-lg + @navbar-fixed-side-submenu-width-lg);
}
}
}

View File

@ -21,31 +21,101 @@
@media (max-width: @screen-xs-max) {
width: @navbar-fixed-side-width-xs;
&.navbar-fixed-side-has-submenu {
width: (@navbar-fixed-side-width-xs + @navbar-fixed-side-submenu-width-xs);
}
top: 0px;
right: 0px;
bottom: 0px;
.nav-submenu {
position: absolute;
top: 0px;
left: 0px;
bottom: 0px;
width: @navbar-fixed-side-submenu-width-md;
}
}
@media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
width: @navbar-fixed-side-width-sm;
&.navbar-fixed-side-has-submenu {
width: (@navbar-fixed-side-width-sm + @navbar-fixed-side-submenu-width-sm);
}
top: 0px;
left: 0px;
bottom: 0px;
.nav-submenu {
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
width: @navbar-fixed-side-submenu-width-md;
}
}
@media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
width: @navbar-fixed-side-width-md;
&.navbar-fixed-side-has-submenu {
width: (@navbar-fixed-side-width-md + @navbar-fixed-side-submenu-width-md);
}
top: 0px;
left: 0px;
bottom: 0px;
.nav-submenu {
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
width: @navbar-fixed-side-submenu-width-md;
}
}
@media (min-width: @screen-lg-min) {
width: @navbar-fixed-side-width-lg;
&.navbar-fixed-side-has-submenu {
width: (@navbar-fixed-side-width-lg + @navbar-fixed-side-submenu-width-lg);
}
top: 0px;
left: 0px;
bottom: 0px;
.nav-submenu {
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
width: @navbar-fixed-side-submenu-width-md;
}
}
.container-fluid {
padding: 5px;
.nav-main {
padding: 5px 0px 5px 0px;
}
.nav-submenu {
display: none;
background-color: @navbar-inverse-link-active-bg;
.nav.nav-pills {
> li {
margin-right: 0px;
margin-left: 0px;
> a {
border-radius: 0px;
background: none;
&:hover {
background: none;
}
}
}
}
}
overflow: hidden;
@ -54,7 +124,12 @@
margin: 0px;
&.navbar-inverse .nav {
> li {
margin-right: 5px;
margin-left: 5px;
> a {
color: @navbar-inverse-link-color;
background: @navbar-inverse-bg;
@ -91,7 +166,7 @@
}
li.active {
background-color: @navbar-inverse-bg
background-color: @navbar-inverse-bg;
}
}
@ -111,10 +186,70 @@
position: absolute;
bottom: 0px;
}
&.navbar-fixed-side-has-submenu {
.nav-submenu {
display: inherit;
}
@media (max-width: @screen-xs-max) {
.nav-main {
margin-left: @navbar-fixed-side-submenu-width-xs;
a {
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
}
li {
&.active {
margin-left: 0px;
a {
padding-left: 10px;
}
}
}
}
}
@media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {
.nav-main {
margin-right: @navbar-fixed-side-submenu-width-sm;
}
}
@media (min-width: @screen-md-min) and (max-width: @screen-md-max) {
.nav-main {
margin-right: @navbar-fixed-side-submenu-width-md;
}
}
@media (min-width: @screen-lg-min) {
.nav-main {
margin-right: @navbar-fixed-side-submenu-width-lg;
}
}
@media (min-width: @screen-sm-min) {
.nav-main {
li {
&.active {
margin-right: 0px;
a {
padding-right: 10px;
}
}
}
a {
border-top-right-radius: 0px;
border-bottom-right-radius: 0px;
}
}
}
}
}
}
// Stacked pills
.nav-stacked {
> li {

View File

@ -25,3 +25,4 @@
.@{fa-css-prefix}-sb-story:before { content: @fa-var-list-ul; }
.@{fa-css-prefix}-sb-project:before { content: @fa-var-cube; }
.@{fa-css-prefix}-sb-project-group:before { content: @fa-var-cubes; }
.@{fa-css-prefix}-sb-team:before { content: @fa-var-users; }

View File

@ -100,6 +100,12 @@
@navbar-fixed-side-width-md: 90px;
@navbar-fixed-side-width-lg: 90px;
// Sizes for the side navbar submenu at different container sizes.
@navbar-fixed-side-submenu-width-xs: 40px;
@navbar-fixed-side-submenu-width-sm: 40px;
@navbar-fixed-side-submenu-width-md: 40px;
@navbar-fixed-side-submenu-width-lg: 40px;
// Form Controls
@input-height-h1: (ceil(@font-size-h1 * @line-height-large) + (@padding-base-vertical * 2));