[PATCH v3] 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. V3 Fixes: Review comments from Aline taken care Implementing same color for all tabs in kimchi 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 | 5 +- ui/css/src/modules/_navbar-flat.scss | 7 +- ui/css/src/modules/_toolbar.scss | 16 +++- ui/css/src/modules/_wok-variables.scss | 8 +- ui/css/src/wok.scss | 6 +- ui/js/src/wok.main.js | 113 ++++++++++++++++++----- ui/pages/wok-ui.html.tmpl | 8 +- 8 files changed, 125 insertions(+), 40 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..5a3bd7a 100644 --- a/src/wok/plugins/kimchi/ui/config/tab-ext.xml +++ b/src/wok/plugins/kimchi/ui/config/tab-ext.xml @@ -1,30 +1,27 @@ <?xml version="1.0" encoding="utf-8"?> <tabs-ext> + <functionality>Virtualization</functionality> <tab> <access role="admin" mode="admin"/> <access role="user" mode="byInstance"/> - <class>guests</class> <title>Guests</title> <path>plugins/kimchi/guests.html</path> </tab> <tab> <access role="admin" mode="admin"/> <access role="user" mode="none"/> - <class>templates</class> <title>Templates</title> <path>plugins/kimchi/templates.html</path> </tab> <tab> <access role="admin" mode="admin"/> <access role="user" mode="read-only"/> - <class>storage</class> <title>Storage</title> <path>plugins/kimchi/storage.html</path> </tab> <tab> <access role="admin" mode="admin"/> <access role="user" mode="read-only"/> - <class>network</class> <title>Network</title> <path>plugins/kimchi/network.html</path> </tab> diff --git a/ui/css/src/modules/_navbar-flat.scss b/ui/css/src/modules/_navbar-flat.scss index 5518fc6..384e755 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; } } @@ -894,4 +895,4 @@ } } } -} +} \ No newline at end of file diff --git a/ui/css/src/modules/_toolbar.scss b/ui/css/src/modules/_toolbar.scss index 744d48d..f6bc146 100644 --- a/ui/css/src/modules/_toolbar.scss +++ b/ui/css/src/modules/_toolbar.scss @@ -67,11 +67,23 @@ @each $page, $bgcolor in $colors { ##{$page}-root-container .navbar-default.toolbar { - background-color: $bgcolor !important; + @if $page=='guests' or $page=='templates' or $page == 'storage' or $page=='network'{ + background-color: $guests-color !important; + }@else if $page =='host' or $page=='administration'{ + background-color: $hosts-color !important; + } + @if $page == 'storage' { .navbar-right.tools > li > a { color: $gray-base !important; } } } -} \ 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..3b7a53c 100644 --- a/ui/css/src/modules/_wok-variables.scss +++ b/ui/css/src/modules/_wok-variables.scss @@ -55,12 +55,16 @@ $networks-color: #7f1c7d !default; $administration-color: #d9182d !default; $colors: ( + hostSelected: #008abf, host: #008abf, guests: #8cc63f, - templates: #00a6a0, + templates: #00a6a0, storage: #feb813, network: #7f1c7d, - administration: #d9182d + administration: #d9182d, + virtualizationTab: #59930c, + hostTab: #00578c, + virtualizationSelected: #8cc63f ); diff --git a/ui/css/src/wok.scss b/ui/css/src/wok.scss index cdb0430..5cc6197 100755 --- a/ui/css/src/wok.scss +++ b/ui/css/src/wok.scss @@ -29,7 +29,11 @@ padding-left: 80px !important; padding-right: 60px !important; } - +#navigation-bar { + padding-left: 0 !important; + padding-right:0 !important; + width:100%; +} // Override alert .alert { border-width: $alert-border-width; diff --git a/ui/js/src/wok.main.js b/ui/js/src/wok.main.js index 1330ac1..6531e88 100644 --- a/ui/js/src/wok.main.js +++ b/ui/js/src/wok.main.js @@ -27,7 +27,6 @@ wok.main = function() { var tabsHtml = []; $(tabs).each(function(i, tab) { var title = tab['title']; - var cssClass = tab['css']; var path = tab['path']; var mode = tab['mode']; if (mode != 'none') { @@ -35,7 +34,7 @@ wok.main = function() { var disableHelp = (helpPath.length == 0 ? "disableHelp" : helpPath); tabsHtml.push( '<li>', - '<a class="item ', disableHelp,' ',cssClass,'" href="', path, '">', + '<a class="item ', disableHelp,' ','" href="', path, '">', title, '</a>', '<input id="helpPathId" name="helpPath" class="sr-only" value="' + helpPath + '" type="hidden"/>', @@ -45,9 +44,26 @@ 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,8 +85,16 @@ 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) { @@ -89,7 +113,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 +126,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'] @@ -112,17 +146,22 @@ wok.main = function() { if(tabs.length===0){ DEFAULT_HASH = 'wok-empty'; }else{ - // Remove file extension from 'defaultTabPath' - DEFAULT_HASH = defaultTabPath && - defaultTabPath.substring(0, defaultTabPath.lastIndexOf('.')) - } - $('#nav-menu ul.navbar-nav li.hostname').after(genTabs(tabs)); - wok.getHostname(); - - callback && callback(); - }, function(data) { - wok.message.error(data.responseJSON.reason); - }, true); + // Remove file extension from 'defaultTabPath' + DEFAULT_HASH = defaultTabPath && + defaultTabPath.substring(0, defaultTabPath.lastIndexOf('.')) + } + $('#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(defaultFunctionalTab+'Selected').focus(); + + wok.getHostname(); + + callback && callback(); + }, function(data) { + wok.message.error(data.responseJSON.reason); + }, true); }; var onLanguageChanged = function(lang) { @@ -146,21 +185,21 @@ 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 + '"]'); - if (tab.length === 0 && url!='wok-empty.html') { + var tab = $('#tabPanel ul.navbar-nav li a[href="' + url + '"]'); + if (tab.length === 0 && url!='wok-empty.html'){ location.hash = ''; return; } - //Remove the tab arrow indicator for no plugin if(url=='wok-empty.html'){ $('#main').html('No plugins installed currently.You can download the available plugins <a href="https://github.com/kimchi-project/kimchi">Kimchi</a> and <a href="https://github.com/kimchi-project/ginger">Ginger</a> from Github').addClass('noPluginMessage'); }else{ - - // Update the visual style of tabs; focus the selected one. - $('#nav-menu ul li').removeClass('active'); + var tab = $('#tabPanel ul.navbar-nav li a[href="' + url + '"]'); + var plugin = $('#nav-menu ul li.active a').text(); + // Update the visual style of tabs; focus the selected one. + $('#tabPanel ul li').removeClass('active'); $(tab).parent().addClass('active'); - $(tab).focus(); + $(tab).addClass(plugin+'Selected').focus(); // Disable Help button according to selected tab if ($(tab).hasClass("disableHelp")) { @@ -238,7 +277,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 +293,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(functionalTab+'Selected'); + 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() { 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
participants (2)
-
Aline Manera
-
atreyee@linux.vnet.ibm.com