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:
parent
a0cc35c72f
commit
8cf3d9ff4f
@ -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
|
||||
|
22
src/app/admin/template/admin_submenu.html
Normal file
22
src/app/admin/template/admin_submenu.html
Normal 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>
|
57
src/app/storyboard/controller/application_controller.js
Normal file
57
src/app/storyboard/controller/application_controller.js
Normal 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;
|
||||
|
||||
});
|
@ -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>
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
@ -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; }
|
||||
|
@ -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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user