Repository: ambari Updated Branches: refs/heads/side-navigation-feature-branch cc4c04e5b -> c7164d8ea
AMBARI-19983. Externalize the logic for making navigation bar interactive (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c7164d8e Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c7164d8e Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c7164d8e Branch: refs/heads/side-navigation-feature-branch Commit: c7164d8eaaacc62e4d56f8f8ff03b74b1a0d46af Parents: cc4c04e Author: Oleg Nechiporenko <[email protected]> Authored: Mon Feb 13 13:47:47 2017 +0200 Committer: Oleg Nechiporenko <[email protected]> Committed: Mon Feb 13 13:47:47 2017 +0200 ---------------------------------------------------------------------- ambari-web/app/assets/data/clusters/info.json | 11 +++ ambari-web/app/styles/side_navigation.less | 41 -------- .../app/styles/theme/bootstrap-ambari.css | 54 +++++++---- ambari-web/app/templates/application.hbs | 8 +- .../app/templates/main/side-menu-item.hbs | 4 +- ambari-web/app/views/application.js | 39 +++----- ambari-web/app/views/main/menu.js | 8 -- ambari-web/brunch-config.js | 3 +- .../vendor/scripts/theme/bootstrap-ambari.js | 99 ++++++++++++++++++++ 9 files changed, 168 insertions(+), 99 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/c7164d8e/ambari-web/app/assets/data/clusters/info.json ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/clusters/info.json b/ambari-web/app/assets/data/clusters/info.json new file mode 100644 index 0000000..95003f9 --- /dev/null +++ b/ambari-web/app/assets/data/clusters/info.json @@ -0,0 +1,11 @@ +{ + "items": [ + { + "Clusters": { + "cluster_name": "tdk", + "provisioning_state": "INSTALLED", + "version": "HDP2.0.1" + } + } + ] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/c7164d8e/ambari-web/app/styles/side_navigation.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/side_navigation.less b/ambari-web/app/styles/side_navigation.less deleted file mode 100644 index 48b8699..0000000 --- a/ambari-web/app/styles/side_navigation.less +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -@import 'common.less'; - -#side-nav { - position: fixed; - top: 0px; - bottom: 0px; - z-index: 2079; - - .side-nav-header { - position: absolute; - top: 0px; - } - .side-nav-menu { - position: fixed; - top: 55px; - bottom: 50px; - overflow-y: auto; - } - .side-nav-footer { - position: fixed; - bottom: 0px; - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/c7164d8e/ambari-web/app/styles/theme/bootstrap-ambari.css ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/theme/bootstrap-ambari.css b/ambari-web/app/styles/theme/bootstrap-ambari.css index adbddcd..d17e423 100644 --- a/ambari-web/app/styles/theme/bootstrap-ambari.css +++ b/ambari-web/app/styles/theme/bootstrap-ambari.css @@ -749,7 +749,7 @@ input.radio:checked + label:after { height: auto; width: 190px; background-color: #323544; - padding: 0px 0px; + padding: 0; overflow: hidden; } .navigation-bar-container ul.nav.side-nav-header { @@ -761,7 +761,7 @@ input.radio:checked + label:after { height: 55px; } .navigation-bar-container ul.nav.side-nav-header li.navigation-header > a.ambari-logo { - padding: 0px; + padding: 0; } .navigation-bar-container ul.nav.side-nav-header li.navigation-header > a.ambari-logo > img { height: 25px; @@ -780,7 +780,7 @@ input.radio:checked + label:after { cursor: pointer; display: inline; color: #fff; - padding: 0px 8px 0px 10px; + padding: 0 8px 0 10px; } .navigation-bar-container ul.nav.side-nav-header li.navigation-header .btn-group span.toggle-icon { margin-bottom: 5px; @@ -832,8 +832,8 @@ input.radio:checked + label:after { } .navigation-bar-container ul.nav.side-nav-menu li, .navigation-bar-container ul.nav.side-nav-footer li { - padding: 0px; - margin: 0px; + padding: 0; + margin: 0; } .navigation-bar-container ul.nav.side-nav-menu li a, .navigation-bar-container ul.nav.side-nav-footer li a { @@ -879,7 +879,7 @@ input.radio:checked + label:after { color: #3fae2a; font-size: 20px; position: relative; - padding: 0px 15px; + padding: 0 15px; left: calc(30%); } .navigation-bar-container ul.nav.side-nav-menu li.navigation-footer a .navigation-icon:hover, @@ -967,7 +967,7 @@ input.radio:checked + label:after { width: 50px; } .navigation-bar-container.collapsed ul.nav.side-nav-header li.navigation-header { - padding: 15px 0px 15px 17px; + padding: 15px 0 15px 17px; } .navigation-bar-container.collapsed ul.nav.side-nav-header li.navigation-header span.ambari-header, .navigation-bar-container.collapsed ul.nav.side-nav-header li.navigation-header span.toggle-icon, @@ -980,7 +980,7 @@ input.radio:checked + label:after { } .navigation-bar-container.collapsed ul.nav.side-nav-menu li a, .navigation-bar-container.collapsed ul.nav.side-nav-footer li a { - padding: 15px 0px 15px 17px; + padding: 15px 0 15px 17px; width: 50px; } .navigation-bar-container.collapsed ul.nav.side-nav-menu li a .navigation-menu-item, @@ -991,24 +991,18 @@ input.radio:checked + label:after { } .navigation-bar-container.collapsed ul.nav.side-nav-menu li.navigation-footer a .navigation-icon, .navigation-bar-container.collapsed ul.nav.side-nav-footer li.navigation-footer a .navigation-icon { - padding: 0px 5px; - left: 0px; + padding: 0 5px; + left: 0; } .navigation-bar-container.collapsed ul.nav.side-nav-menu li ul.sub-menu, .navigation-bar-container.collapsed ul.nav.side-nav-footer li ul.sub-menu { display: none; width: 190px; - position: fixed; + position: absolute; + z-index: 100; + top: 0; left: 50px; } -.navigation-bar-container.collapsed ul.nav.side-nav-menu li ul.admin-submenu, -.navigation-bar-container.collapsed ul.nav.side-nav-footer li ul.admin-submenu { - top: 249px; -} -.navigation-bar-container.collapsed ul.nav.side-nav-menu li ul.services-submenu, -.navigation-bar-container.collapsed ul.nav.side-nav-footer li ul.services-submenu { - top: 103px; -} .navigation-bar-container.collapsed ul.nav.side-nav-menu li:hover ul.sub-menu, .navigation-bar-container.collapsed ul.nav.side-nav-footer li:hover ul.sub-menu { display: block; @@ -1043,6 +1037,28 @@ input.radio:checked + label:after { .navigation-bar-container.collapsed ul.nav.side-nav-footer li.submenu-li.active > a { padding-left: 19px; } +.navigation-bar-fit-height { + position: fixed; + top: 0; + bottom: 0; + z-index: 2079; +} +.navigation-bar-fit-height .side-nav-header { + position: absolute; + top: 0; +} +.navigation-bar-fit-height .side-nav-menu { + position: fixed; + top: 55px; + bottom: 50px; +} +.navigation-bar-fit-height .side-nav-footer { + position: fixed; + bottom: 0; +} +.navigation-bar-fit-height .navigation-bar-container:not(.collapsed) .side-nav-menu { + overflow-y: auto; +} h1, h2, h3, http://git-wip-us.apache.org/repos/asf/ambari/blob/c7164d8e/ambari-web/app/templates/application.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/application.hbs b/ambari-web/app/templates/application.hbs index f18d314..25c3311 100644 --- a/ambari-web/app/templates/application.hbs +++ b/ambari-web/app/templates/application.hbs @@ -20,7 +20,9 @@ {{view App.ClockView}} {{/if}} -<div id="side-nav" class="navigation-bar-container"> +{{#if App.router.mainController.isClusterDataLoaded}} +<div id="side-nav" class="navigation-bar"> + <div class="navigation-bar-container"> <ul class="side-nav-header nav nav-pills nav-stacked"> <li class="navigation-header"> {{#if enableLinks}} @@ -53,11 +55,13 @@ <ul class="side-nav-footer nav nav-pills nav-stacked"> <li class="navigation-footer"> <a> - <span class="navigation-icon icon-double-angle-left" data-toggle="collapseSideNav"></span> + <span class="navigation-icon icon-double-angle-left" data-toggle="collapse-side-nav"></span> </a> </li> </ul> + </div> </div> +{{/if}} <div id="main"> <div id="top-nav"> http://git-wip-us.apache.org/repos/asf/ambari/blob/c7164d8e/ambari-web/app/templates/main/side-menu-item.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/side-menu-item.hbs b/ambari-web/app/templates/main/side-menu-item.hbs index 27739c8..f32ce02 100644 --- a/ambari-web/app/templates/main/side-menu-item.hbs +++ b/ambari-web/app/templates/main/side-menu-item.hbs @@ -18,7 +18,7 @@ <!--dropdown menu for the items had dropdowns--> {{#if view.isServicesItem}} - <a {{bindAttr class="view.content.isView:views-button-container"}} data-toggle="collapseSubMenu"> + <a {{bindAttr class="view.content.isView:views-button-container"}} data-toggle="collapse-sub-menu"> <span {{bindAttr class=":navigation-icon view.content.iconClass"}}></span> <span class="navigation-menu-item">{{{unbound view.content.label}}}</span> <span class="toggle-icon glyphicon glyphicon-menu-down"></span> @@ -26,7 +26,7 @@ {{view App.SideNavServiceMenuView}} {{else}} {{#if view.isAdminItem}} - <a {{bindAttr class="view.content.isView:views-button-container"}} data-toggle="collapseSubMenu"> + <a {{bindAttr class="view.content.isView:views-button-container"}} data-toggle="collapse-sub-menu"> <span {{bindAttr class=":navigation-icon view.content.iconClass"}}></span> <span class="navigation-menu-item">{{{unbound view.content.label}}}</span> <span class="toggle-icon glyphicon glyphicon-menu-down"></span> http://git-wip-us.apache.org/repos/asf/ambari/blob/c7164d8e/ambari-web/app/views/application.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/application.js b/ambari-web/app/views/application.js index f79aad9..207e77f 100644 --- a/ambari-web/app/views/application.js +++ b/ambari-web/app/views/application.js @@ -146,32 +146,19 @@ App.ApplicationView = Em.View.extend({ } return true; }); + }, - $('[data-toggle=collapseSideNav]').click(function() { - $('.navigation-bar-container').toggleClass('collapsed').promise().done(function(){ - - if ($('.navigation-bar-container').hasClass('collapsed')) { - // set submenu invisible when collapsed - $('.navigation-bar-container.collapsed ul.sub-menu').hide(); - // set the hover effect when collapsed, should show sub-menu on hovering - $(".navigation-bar-container.collapsed .side-nav-menu>li").hover(function() { - $(this).children("ul.sub-menu").show(); - }, function() { - $(this).children("ul.sub-menu").hide(); - }); - } else { - // keep showing all submenu - $('.navigation-bar-container ul.sub-menu').show(); - $(".navigation-bar-container .side-nav-menu>li").unbind('mouseenter mouseleave'); - $('[data-toggle=collapseSubMenu]').children('.toggle-icon').removeClass('glyphicon-menu-right'); - $('[data-toggle=collapseSubMenu]').children('.toggle-icon').addClass('glyphicon-menu-down'); - } + /** + * Navigation Bar should be initialized after cluster data is loaded + */ + initNavigationBar: function () { + if (App.get('router.mainController.isClusterDataLoaded')) { + Em.run.next(() => $('.navigation-bar').navigationBar({ + fitHeight: true, + collapseNavBarClass: 'icon-double-angle-left', + expandNavBarClass: 'icon-double-angle-right' + })); + } + }.observes('App.router.mainController.isClusterDataLoaded') - //set main content left margin based on the width of side-nav - $('#main').css('margin-left', $('.navigation-bar-container').width()); - $('footer').css('margin-left', $('.navigation-bar-container').width()); - }); - $('[data-toggle=collapseSideNav]').toggleClass('icon-double-angle-right');//, 100, "easeOutSine"); - }); - } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/c7164d8e/ambari-web/app/views/main/menu.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/menu.js b/ambari-web/app/views/main/menu.js index d82d56a..2b8b5af 100644 --- a/ambari-web/app/views/main/menu.js +++ b/ambari-web/app/views/main/menu.js @@ -60,14 +60,6 @@ App.MainSideMenuView = Em.CollectionView.extend({ classNames: ['mainmenu-li'], - didInsertElement: function () { - $('[data-toggle=collapseSubMenu]').off('click').on('click', function(event){ - $(this).siblings('.sub-menu').slideToggle(600); - $(this).children('.toggle-icon').toggleClass('glyphicon-menu-right glyphicon-menu-down'); - event.stopPropagation(); - }); - }, - active: function () { if (App.get('clusterName') && App.router.get('clusterController.isLoaded')) { var lastUrl = App.router.location.lastSetURL || location.href.replace(/^[^#]*#/, ''); http://git-wip-us.apache.org/repos/asf/ambari/blob/c7164d8e/ambari-web/brunch-config.js ---------------------------------------------------------------------- diff --git a/ambari-web/brunch-config.js b/ambari-web/brunch-config.js index d646fdc..31eb1cb 100644 --- a/ambari-web/brunch-config.js +++ b/ambari-web/brunch-config.js @@ -81,7 +81,8 @@ module.exports.config = { 'vendor/scripts/jquery.flexibleArea.js', 'vendor/scripts/FileSaver.js', 'vendor/scripts/Blob.js', - 'vendor/scripts/pluralize.js' + 'vendor/scripts/pluralize.js', + 'vendor/scripts/theme/bootstrap-ambari.js' ] } }, http://git-wip-us.apache.org/repos/asf/ambari/blob/c7164d8e/ambari-web/vendor/scripts/theme/bootstrap-ambari.js ---------------------------------------------------------------------- diff --git a/ambari-web/vendor/scripts/theme/bootstrap-ambari.js b/ambari-web/vendor/scripts/theme/bootstrap-ambari.js new file mode 100644 index 0000000..2c97dd6 --- /dev/null +++ b/ambari-web/vendor/scripts/theme/bootstrap-ambari.js @@ -0,0 +1,99 @@ +'use strict'; + +(function ($) { + + /** + * jQuery plugin for navigation bars + * Usage: + * <pre> + * $('.navigation-bar').navigationBar(); + * </pre> + * + * @param {object} options see <code>$.fn.navigationBar.defaults</code> + * @returns {$} + */ + + $.fn.navigationBar = function (options) { + + var settings = $.extend({}, $.fn.navigationBar.defaults, options); + + return this.each(function () { + + var containerSelector = '.navigation-bar-container'; + var $navigationContainer = $(this).find(containerSelector); + var $sideNavToggler = $(this).find('[data-toggle=' + settings.navBarToggleDataAttr + ']'); + var $subMenuToggler = $(this).find('[data-toggle=' + settings.subMenuNavToggleDataAttr + ']'); + + if (settings.fitHeight) { + $(this).addClass('navigation-bar-fit-height'); + } + + /** + * Slider for sub menu + */ + $subMenuToggler.off('click').on('click', function (event) { + // ignore click if navigation-bar is collapsed + if ($navigationContainer.hasClass('collapsed')) { + return false; + } + var $this = $(this); + $this.siblings('.sub-menu').slideToggle(600); + $this.children('.toggle-icon').toggleClass(settings.menuLeftClass + ' ' + settings.menuDownClass); + event.stopPropagation(); + return false; + }); + + /** + * Expand/collapse navigation bar + */ + $sideNavToggler.click(function () { + + $navigationContainer.toggleClass('collapsed').promise().done(function () { + var subMenuSelector = 'ul.sub-menu'; + var $subMenus = $navigationContainer.find(subMenuSelector); + var $subMenuItems = $navigationContainer.find('.side-nav-menu>li'); + if ($navigationContainer.hasClass('collapsed')) { + // set sub menu invisible when collapsed + $subMenus.hide(); + // set the hover effect when collapsed, should show sub-menu on hovering + $subMenuItems.hover(function () { + $(this).find(subMenuSelector).show(); + }, function () { + $(this).find(subMenuSelector).hide(); + }); + } else { + // keep showing all sub menu + $subMenus.show(); + $subMenuItems.unbind('mouseenter mouseleave'); + $navigationContainer.find('.toggle-icon').removeClass(settings.menuLeftClass).addClass(settings.menuDownClass); + } + + //set main content left margin based on the width of side-nav + var containerWidth = $navigationContainer.width(); + if (settings.moveLeftContent) { + $(settings.content).css('margin-left', containerWidth); + } + if (settings.moveLeftFooter) { + $(settings.footer).css('margin-left', containerWidth); + } + $sideNavToggler.toggleClass(settings.collapseNavBarClass + ' ' + settings.expandNavBarClass); + }); + return false; + }); + }); + }; + + $.fn.navigationBar.defaults = { + fitHeight: false, + content: '#main', + footer: 'footer', + moveLeftContent: true, + moveLeftFooter: true, + menuLeftClass: 'glyphicon-menu-right', + menuDownClass: 'glyphicon-menu-down', + collapseNavBarClass: 'fa-angle-double-left', + expandNavBarClass: 'fa-angle-double-right', + navBarToggleDataAttr: 'collapse-side-nav', + subMenuNavToggleDataAttr: 'collapse-sub-menu' + }; +})(jQuery); \ No newline at end of file
