[PATCH v2] New Navigation bar

From: Atreyee Mukhopadhyay <atreyee@linux.vnet.ibm.com> This patch is to implement new feature mentioned in issue #746. First level navigation bar with Host and Virtualization tabs. Second level tab navigation based on first level navigation. V2 Fixes: Review comments from Aline taken care 1. alignement of second level navigation with first level navigation 2. second level tab color to fit the window Atreyee Mukhopadhyay (1): Issue #746 : New navigation bar. src/wok/plugins/gingerbase/ui/config/tab-ext.xml | 2 +- src/wok/plugins/kimchi/ui/config/tab-ext.xml | 1 + ui/css/src/modules/_navbar-flat.scss | 5 +- ui/css/src/modules/_toolbar.scss | 9 ++- ui/css/src/modules/_wok-variables.scss | 9 ++- ui/css/src/wok.scss | 4 ++ ui/js/src/wok.main.js | 87 +++++++++++++++++++++--- ui/pages/wok-ui.html.tmpl | 8 ++- 8 files changed, 105 insertions(+), 20 deletions(-) -- 2.1.0

From: Atreyee Mukhopadhyay <atreyee@linux.vnet.ibm.com> First level navigation bar with Host and Virtualization tabs. Second level tab navigation based on first level navigation. --- src/wok/plugins/gingerbase/ui/config/tab-ext.xml | 2 +- src/wok/plugins/kimchi/ui/config/tab-ext.xml | 1 + ui/css/src/modules/_navbar-flat.scss | 5 +- ui/css/src/modules/_toolbar.scss | 9 ++- ui/css/src/modules/_wok-variables.scss | 9 ++- ui/css/src/wok.scss | 4 ++ ui/js/src/wok.main.js | 87 +++++++++++++++++++++--- ui/pages/wok-ui.html.tmpl | 8 ++- 8 files changed, 105 insertions(+), 20 deletions(-) diff --git a/src/wok/plugins/gingerbase/ui/config/tab-ext.xml b/src/wok/plugins/gingerbase/ui/config/tab-ext.xml index 8366f1f..3d3f51e 100644 --- a/src/wok/plugins/gingerbase/ui/config/tab-ext.xml +++ b/src/wok/plugins/gingerbase/ui/config/tab-ext.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <tabs-ext> + <functionality>Host</functionality> <tab> <access role="admin" mode="admin"/> <access role="user" mode="none"/> - <class>host</class> <title>Host</title> <path>plugins/gingerbase/host.html</path> </tab> diff --git a/src/wok/plugins/kimchi/ui/config/tab-ext.xml b/src/wok/plugins/kimchi/ui/config/tab-ext.xml index 415dbf1..9adabe0 100644 --- a/src/wok/plugins/kimchi/ui/config/tab-ext.xml +++ b/src/wok/plugins/kimchi/ui/config/tab-ext.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <tabs-ext> + <functionality>Virtualization</functionality> <tab> <access role="admin" mode="admin"/> <access role="user" mode="byInstance"/> diff --git a/ui/css/src/modules/_navbar-flat.scss b/ui/css/src/modules/_navbar-flat.scss index 5518fc6..a2921e4 100644 --- a/ui/css/src/modules/_navbar-flat.scss +++ b/ui/css/src/modules/_navbar-flat.scss @@ -580,7 +580,7 @@ color: $navbar-default-link-color; text-decoration: none; outline: none; - min-width: 190px; + min-width: 210px; text-align: center; height: $navbar-height; @@ -654,7 +654,7 @@ margin: 0; padding: 8px 0; vertical-align: top; - width: 180px; + width:210px; padding-right: 24px; @include box-sizing(border-box); @@ -668,6 +668,7 @@ overflow: hidden; white-space: nowrap; text-overflow: ellipsis; + margin-left:80px; } } diff --git a/ui/css/src/modules/_toolbar.scss b/ui/css/src/modules/_toolbar.scss index 744d48d..32ea52e 100644 --- a/ui/css/src/modules/_toolbar.scss +++ b/ui/css/src/modules/_toolbar.scss @@ -74,4 +74,11 @@ } } } -} \ No newline at end of file +} + +@each $tab, $bgcolor in $colors { + +#tabPanel.#{$tab}{ + background-color: map-get($colors,$tab) !important; + } +} diff --git a/ui/css/src/modules/_wok-variables.scss b/ui/css/src/modules/_wok-variables.scss index d67672d..3288d8b 100644 --- a/ui/css/src/modules/_wok-variables.scss +++ b/ui/css/src/modules/_wok-variables.scss @@ -55,12 +55,15 @@ $networks-color: #7f1c7d !default; $administration-color: #d9182d !default; $colors: ( - host: #008abf, + default: #008abf, + host: #008abf, guests: #8cc63f, templates: #00a6a0, storage: #feb813, network: #7f1c7d, - administration: #d9182d + administration: #d9182d, + virtualizationTab: #59930c, + hostTab: #00578c ); @@ -978,4 +981,4 @@ $color-grey-arrow: rgb(204, 204, 204); $width-default: 220px; -$zindex-select-dropdown: 1035 !default; \ No newline at end of file +$zindex-select-dropdown: 1035 !default; diff --git a/ui/css/src/wok.scss b/ui/css/src/wok.scss index cdb0430..625404a 100755 --- a/ui/css/src/wok.scss +++ b/ui/css/src/wok.scss @@ -29,6 +29,10 @@ padding-left: 80px !important; padding-right: 60px !important; } +#navigation-bar { + padding-left: 0 !important; + padding-right:0 !important; + width:100%;} // Override alert .alert { diff --git a/ui/js/src/wok.main.js b/ui/js/src/wok.main.js index 1330ac1..73a7bc4 100644 --- a/ui/js/src/wok.main.js +++ b/ui/js/src/wok.main.js @@ -27,7 +27,7 @@ wok.main = function() { var tabsHtml = []; $(tabs).each(function(i, tab) { var title = tab['title']; - var cssClass = tab['css']; + var cssClass = tab['css']? tab['css']:'default'; var path = tab['path']; var mode = tab['mode']; if (mode != 'none') { @@ -45,9 +45,25 @@ wok.main = function() { }); return tabsHtml.join(''); }; - + var genFunctTabs = function(tabs){ + var functionalTabHtml = []; + var functionalTabs = Object.keys(tabs); + var css =""; + $(functionalTabs).each(function(i, tab) { + functionalTabHtml.push( + '<li>', + '<a class="item',' ',tab.toLowerCase(),'Tab','" href="#">', + tab, + '</a>', + '</li>' + ); + }); + return functionalTabHtml.join(''); + }; var parseTabs = function(xmlData) { var tabs = []; + var functionalTabs = {}; + var functionality = $(xmlData).find('functionality').text(); $(xmlData).find('tab').each(function() { var $tab = $(this); var titleKey = $tab.find('title').text(); @@ -69,10 +85,20 @@ wok.main = function() { document.location.href = 'login.html'; } }); + var tabsDetails = JSON.parse(wok.cookie.get('tabs')); - return tabs; + var isExisting = tabsDetails[functionality] && (tabsDetails[functionality].length)>0; + + if(isExisting){ + tabs.push.apply(tabs,tabsDetails[functionality]); + } + + functionalTabs[functionality] = tabs; + + return functionalTabs; }; + var retrieveTabs = function(url) { var tabs; $.ajax({ @@ -89,7 +115,8 @@ wok.main = function() { var pluginI18nUrl = 'plugins/{plugin}/i18n.json'; var DEFAULT_HASH; var buildTabs = function(callback) { - var tabs = []; + var tabs = {}; + wok.cookie.set('tabs',JSON.stringify(tabs)); wok.listPlugins(function(plugins) { $(plugins).each(function(i, p) { var url = wok.substitute(pluginConfigUrl, { @@ -101,10 +128,19 @@ wok.main = function() { wok.getI18n(function(i18nObj){ $.extend(i18n, i18nObj)}, function(i18nObj){ //i18n is not define by plugin }, i18nUrl, true); - tabs.push.apply(tabs, retrieveTabs(url)); + tabs = $.extend({},tabs, retrieveTabs(url)); + wok.cookie.set('tabs',JSON.stringify(tabs)); }); - var defaultTab = tabs[0] + var orderedtabs ={}; + Object.keys(tabs).sort().forEach(function(key){ + orderedtabs[key]=tabs[key]; + }); + + //defaulting the first tab in second level + var defaultFunctionalTab = Object.keys(orderedtabs)[0]; + + var defaultTab = tabs[defaultFunctionalTab][0]; var defaultTabPath = defaultTab && defaultTab['path'] @@ -116,7 +152,12 @@ wok.main = function() { DEFAULT_HASH = defaultTabPath && defaultTabPath.substring(0, defaultTabPath.lastIndexOf('.')) } - $('#nav-menu ul.navbar-nav li.hostname').after(genTabs(tabs)); + $('#nav-menu ul.navbar-nav li.hostname').after(genFunctTabs(orderedtabs)); + $('#nav-menu ul.navbar-nav li a.item').first().parent().addClass('active').focus(); + $('#tabPanel').addClass(defaultFunctionalTab+'Tab'); + $(genTabs(tabs[defaultFunctionalTab])).appendTo('#tabPanel ul'); + $('#tabPanel ul li a.item').first().addClass('default').focus(); + wok.getHostname(); callback && callback(); @@ -146,7 +187,7 @@ wok.main = function() { * point to the tab. If nothing found, inform user the URL is invalid * and clear location.hash to jump to home page. */ - var tab = $('#nav-menu ul li a[href="' + url + '"]'); + var tab = $('#tabPanel ul.navbar-nav li a[href="' + url + '"]'); if (tab.length === 0 && url!='wok-empty.html') { location.hash = ''; return; @@ -158,7 +199,7 @@ wok.main = function() { }else{ // Update the visual style of tabs; focus the selected one. - $('#nav-menu ul li').removeClass('active'); + $('#tabPanel ul li').removeClass('active'); $(tab).parent().addClass('active'); $(tab).focus(); @@ -238,7 +279,7 @@ wok.main = function() { * Register click listener of tabs. Replace the default reloading page * behavior of <a> with Ajax loading. */ - $('#nav-menu ul li').on('click', 'a.item', function(event) { + $('#tabPanel ul').on('click', 'a.item', function(event) { var href = $(this).attr('href'); // Remove file extension from 'href' location.hash = href.substring(0,href.lastIndexOf('.')) @@ -254,6 +295,30 @@ wok.main = function() { event.preventDefault(); }); + /* + * Register click listener of second level tabs. Replace the default reloading page + * behavior of <a> with Ajax loading. + */ + $('#nav-menu ul li').on('click', 'a.item', function(event) { + var functionalTab = $(this).text(); + var previousSelection = $('#nav-menu ul li.active a').text(); + $('#tabPanel').removeClass(previousSelection+'Tab'); + + $('#nav-menu ul li').removeClass('active'); + $(this).parent().addClass('active').focus(); + + $('#tabPanel').addClass(functionalTab+'Tab'); + var tabs = JSON.parse(wok.cookie.get('tabs')); + $('#tabPanel ul').empty(); + $(genTabs(tabs[functionalTab])).appendTo('#tabPanel ul'); + var firstTab = $('#tabPanel ul.navbar-nav li').first(); + $(firstTab).addClass('active'); + $('a.item',firstTab).addClass('default'); + var href= $('a.item',firstTab).attr('href'); + location.hash = href.substring(0,href.lastIndexOf('.')); + event.preventDefault(); + + }); // Perform logging out via Ajax request. $('#btn-logout').on('click', function() { wok.logout(function() { @@ -392,4 +457,4 @@ wok.openHelp = function(e) { var url = $(tab).parent().find("input[name='helpPath']").val(); window.open(url, "Wok Help"); e.preventDefault(); -}; \ No newline at end of file +}; diff --git a/ui/pages/wok-ui.html.tmpl b/ui/pages/wok-ui.html.tmpl index acfae27..c064d04 100644 --- a/ui/pages/wok-ui.html.tmpl +++ b/ui/pages/wok-ui.html.tmpl @@ -125,7 +125,7 @@ </div> </nav> <nav class="navbar navbar-default"> - <div class="container"> + <div class="container" id="navigation-bar"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#nav-menu" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> @@ -133,10 +133,14 @@ </button> </div> <div class="collapse navbar-collapse" id="nav-menu"> - <ul class="nav navbar-nav"> + <ul id="functionalTabPanel" class="nav navbar-nav"> <li class="hostname"><span class="host-location"></span></li> </ul> </div> + <div class="collapse navbar-collapse" id="tabPanel"> + <ul class="nav navbar-nav"> + </ul> + </div> </div> </nav> </div> -- 2.1.0

Hi Atreyee, Only one comment: the second level tab in Kimchi is being displayed a different colour per tab. We should use green for all them. The same you did for Ginger, which display all tabs in blue. On 18/11/2015 04:08, atreyee@linux.vnet.ibm.com wrote:
From: Atreyee Mukhopadhyay <atreyee@linux.vnet.ibm.com>
This patch is to implement new feature mentioned in issue #746. First level navigation bar with Host and Virtualization tabs. Second level tab navigation based on first level navigation.
V2 Fixes: Review comments from Aline taken care 1. alignement of second level navigation with first level navigation 2. second level tab color to fit the window
Atreyee Mukhopadhyay (1): Issue #746 : New navigation bar.
src/wok/plugins/gingerbase/ui/config/tab-ext.xml | 2 +- src/wok/plugins/kimchi/ui/config/tab-ext.xml | 1 + ui/css/src/modules/_navbar-flat.scss | 5 +- ui/css/src/modules/_toolbar.scss | 9 ++- ui/css/src/modules/_wok-variables.scss | 9 ++- ui/css/src/wok.scss | 4 ++ ui/js/src/wok.main.js | 87 +++++++++++++++++++++--- ui/pages/wok-ui.html.tmpl | 8 ++- 8 files changed, 105 insertions(+), 20 deletions(-)
participants (2)
-
Aline Manera
-
atreyee@linux.vnet.ibm.com