From 39756ad16684db273e1d140b19a7d8a3c26ab5cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 1 Sep 2015 15:27:40 +0200 Subject: [PATCH] Feature #3748: More responsive menu for sunstone --- src/sunstone/etc/sunstone-views/admin.yaml | 2 +- .../etc/sunstone-views/admin_vcenter.yaml | 2 +- src/sunstone/etc/sunstone-views/user.yaml | 2 +- src/sunstone/public/app/app.js | 7 ++ src/sunstone/public/app/sunstone-config.js | 3 +- src/sunstone/public/app/sunstone.js | 4 + src/sunstone/public/app/tabs/provision-tab.js | 15 +-- .../public/app/tabs/provision-tab/header.hbs | 4 - src/sunstone/public/app/utils/menu.js | 87 ++++++++++++++++++ .../app/utils/menu/provision-top-row.hbs | 13 +++ .../public/app/utils/menu/top-row.hbs | 14 +++ .../opennebula-sunstone-v4.14-small.png | Bin 0 -> 10046 bytes src/sunstone/public/scss/app.scss | 36 ++++---- src/sunstone/views/index.erb | 10 +- 14 files changed, 154 insertions(+), 45 deletions(-) create mode 100644 src/sunstone/public/app/utils/menu.js create mode 100644 src/sunstone/public/app/utils/menu/provision-top-row.hbs create mode 100644 src/sunstone/public/app/utils/menu/top-row.hbs create mode 100644 src/sunstone/public/images/opennebula-sunstone-v4.14-small.png diff --git a/src/sunstone/etc/sunstone-views/admin.yaml b/src/sunstone/etc/sunstone-views/admin.yaml index a9e0541373..a6e5aae4e9 100644 --- a/src/sunstone/etc/sunstone-views/admin.yaml +++ b/src/sunstone/etc/sunstone-views/admin.yaml @@ -1,4 +1,4 @@ -small_logo: images/opennebula-sunstone-v4.0-small.png +small_logo: images/opennebula-sunstone-v4.14-small.png provision_logo: images/one_small_logo.png enabled_tabs: dashboard-tab: true diff --git a/src/sunstone/etc/sunstone-views/admin_vcenter.yaml b/src/sunstone/etc/sunstone-views/admin_vcenter.yaml index 3586c21e0e..eaa81d8979 100644 --- a/src/sunstone/etc/sunstone-views/admin_vcenter.yaml +++ b/src/sunstone/etc/sunstone-views/admin_vcenter.yaml @@ -1,4 +1,4 @@ -small_logo: images/opennebula-sunstone-v4.0-small.png +small_logo: images/opennebula-sunstone-v4.14-small.png provision_logo: images/one_small_logo.png enabled_tabs: dashboard-tab: true diff --git a/src/sunstone/etc/sunstone-views/user.yaml b/src/sunstone/etc/sunstone-views/user.yaml index af022fb4ce..6aa5a7cc6c 100644 --- a/src/sunstone/etc/sunstone-views/user.yaml +++ b/src/sunstone/etc/sunstone-views/user.yaml @@ -1,4 +1,4 @@ -small_logo: images/opennebula-sunstone-v4.0-small.png +small_logo: images/opennebula-sunstone-v4.14-small.png provision_logo: images/one_small_logo.png enabled_tabs: dashboard-tab: true diff --git a/src/sunstone/public/app/app.js b/src/sunstone/public/app/app.js index 52671d6ddb..ab3680d63b 100644 --- a/src/sunstone/public/app/app.js +++ b/src/sunstone/public/app/app.js @@ -9,6 +9,7 @@ define(function(require) { var Config = require('sunstone-config'); var OpenNebula = require('opennebula'); var Notifier = require('utils/notifier'); + var Menu = require('utils/menu'); var _tabs; if (Config.isTabEnabled(PROVISION_TAB_ID)) { @@ -65,6 +66,12 @@ define(function(require) { $(document).ready(function() { Sunstone.insertTabs(); + if (Config.isTabEnabled(PROVISION_TAB_ID)){ + Menu.insertProvision(); + }else{ + Menu.insert(); + } + _setupAccordion(); _setupCloseDropdownsOnClick(); _insertUserAndZoneSelector(); diff --git a/src/sunstone/public/app/sunstone-config.js b/src/sunstone/public/app/sunstone-config.js index 3105bd4076..c75c5d2384 100644 --- a/src/sunstone/public/app/sunstone-config.js +++ b/src/sunstone/public/app/sunstone-config.js @@ -109,7 +109,8 @@ define(function(require) { 'autoRefresh' : _config['view']['autorefresh'], 'tableOrder': _config['user_config']['table_order'], 'vncProxyPort': _config['system_config']['vnc_proxy_port'], - 'vncWSS': _config['user_config']['vnc_wss'] + 'vncWSS': _config['user_config']['vnc_wss'], + 'logo': (_config['view']["small_logo"] || "images/one_small_logo.png") } return Config; diff --git a/src/sunstone/public/app/sunstone.js b/src/sunstone/public/app/sunstone.js index e1422eafe5..a876b82de6 100644 --- a/src/sunstone/public/app/sunstone.js +++ b/src/sunstone/public/app/sunstone.js @@ -7,6 +7,7 @@ define(function(require) { var Config = require('sunstone-config'); var Locale = require('utils/locale'); var Notifier = require('utils/notifier'); + var Menu = require('utils/menu'); var TOP_INTERVAL = 10000; //ms var CONFIRM_DIALOG_ID = require('utils/dialogs/confirm/dialogId'); @@ -485,6 +486,9 @@ define(function(require) { return false; } + // Hide the menu in small windows + Menu.entryClick(); + // TODO check if necessary // last_selected_row = null; diff --git a/src/sunstone/public/app/tabs/provision-tab.js b/src/sunstone/public/app/tabs/provision-tab.js index 2c91d3fd95..0d38985bcf 100644 --- a/src/sunstone/public/app/tabs/provision-tab.js +++ b/src/sunstone/public/app/tabs/provision-tab.js @@ -969,25 +969,12 @@ define(function(require) { var tab = $("#"+tab_name); if (Config.isTabEnabled(tab_name)) { - $('.right-header').prepend(TemplateHeader({'logo': Config.provision.logo})); + $('.right-header').prepend(TemplateHeader()); - $(".left-content").remove(); $(".right-content").addClass("large-centered small-centered"); $("#footer").removeClass("right"); $("#footer").addClass("large-centered small-centered"); - //$(".user-zone-info").remove(); - - $("#provision_logout").click(function(){ - OpenNebula.Auth.logout({ - success: function(){ - window.location.href = "login"; - } - }); - - return false; - }); - ProvisionVmsList.generate($(".provision_vms_list_section"), {active: true}); if (Config.isTabPanelEnabled("provision-tab", "templates")) { diff --git a/src/sunstone/public/app/tabs/provision-tab/header.hbs b/src/sunstone/public/app/tabs/provision-tab/header.hbs index bc08375551..d6f7c15b58 100644 --- a/src/sunstone/public/app/tabs/provision-tab/header.hbs +++ b/src/sunstone/public/app/tabs/provision-tab/header.hbs @@ -1,10 +1,6 @@
- - -
-
    {{#isTabPanelEnabled "provision-tab" "users"}}
  • diff --git a/src/sunstone/public/app/utils/menu.js b/src/sunstone/public/app/utils/menu.js new file mode 100644 index 0000000000..ca1f716d57 --- /dev/null +++ b/src/sunstone/public/app/utils/menu.js @@ -0,0 +1,87 @@ +define(function(require) { + + var TopRowHTML = require('hbs!./menu/top-row'); + var ProvisionTopRowHTML = require('hbs!./menu/provision-top-row'); + var Config = require('sunstone-config'); + + return { + 'insert': _insert, + 'insertProvision': _insertProvision, + 'setup': _setup, + 'hide': _hide, + 'show': _show, + 'entryClick': _entryClick, + }; + + function _insert(){ + $('#top-row').html(TopRowHTML({logo: Config.logo})); + + _setup(); + } + + function _insertProvision(){ + $('#top-row').html(ProvisionTopRowHTML({logo: Config.provision.logo})); + + $("#menu-wrapper").remove(); + } + + function _setup(){ + $('#menu-toggle').on('click', function(){ + var hiding = $('.right-content').hasClass("large-10"); + + if(!hiding){ + $('.right-content').toggleClass('large-10'); + $('.right-content').toggleClass('large-12'); + } + + $('#menu-wrapper').toggle(200, function(){ + if(hiding){ + $('.right-content').toggleClass('large-10'); + $('.right-content').toggleClass('large-12'); + } + }); + }); + + var prevWindowLarge = Foundation.utils.is_large_up(); + + $(window).resize(function() { + if(Foundation.utils.is_large_up()){ + $('#menu-wrapper').removeClass("menu-small"); + + if(!prevWindowLarge){ // resizing from small to large, show menu + _show(); + } + + prevWindowLarge = true; + } else { + $('#menu-wrapper').addClass("menu-small"); + + if(prevWindowLarge){ // resizing from large to small, hide menu + _hide(); + } + + prevWindowLarge = false; + } + }); + + $(window).resize(); + } + + function _hide(){ + if($('#menu-wrapper').is(':visible')){ + $('#menu-toggle').click(); + } + } + + function _show(){ + if(!$('#menu-wrapper').is(':visible')){ + $('#menu-toggle').click(); + } + } + + function _entryClick(){ + if(!Foundation.utils.is_large_up()){ + _hide(); + } + } +}); diff --git a/src/sunstone/public/app/utils/menu/provision-top-row.hbs b/src/sunstone/public/app/utils/menu/provision-top-row.hbs new file mode 100644 index 0000000000..9991576ed9 --- /dev/null +++ b/src/sunstone/public/app/utils/menu/provision-top-row.hbs @@ -0,0 +1,13 @@ +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/sunstone/public/app/utils/menu/top-row.hbs b/src/sunstone/public/app/utils/menu/top-row.hbs new file mode 100644 index 0000000000..553005955c --- /dev/null +++ b/src/sunstone/public/app/utils/menu/top-row.hbs @@ -0,0 +1,14 @@ +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/src/sunstone/public/images/opennebula-sunstone-v4.14-small.png b/src/sunstone/public/images/opennebula-sunstone-v4.14-small.png new file mode 100644 index 0000000000000000000000000000000000000000..ca4f2355b71b489faeb644fbc8868115d658574a GIT binary patch literal 10046 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
+
+
+
-
+