From b20a063d7f13f136f06e97137638dc134262c552 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 12 Mar 2012 12:45:38 +0100 Subject: [PATCH 1/5] Feature #1112: Update Sunstone dashboards, allow DS select on image creation, list images in DS in extended info and various small bugfixes. --- .../models/OpenNebulaJSON/ImageJSON.rb | 2 +- src/sunstone/models/SunstoneServer.rb | 15 +++++++- .../public/js/plugins/dashboard-tab.js | 22 ++++++++++-- .../public/js/plugins/dashboard-users-tab.js | 14 +++++++- .../public/js/plugins/datastores-tab.js | 35 +++++++++++++++++-- src/sunstone/public/js/plugins/images-tab.js | 15 ++++++-- src/sunstone/public/js/plugins/vnets-tab.js | 1 + src/sunstone/public/js/sunstone-util.js | 19 +++++++--- 8 files changed, 109 insertions(+), 14 deletions(-) diff --git a/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb b/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb index 11c03966ee..99a0bdf04b 100644 --- a/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/ImageJSON.rb @@ -37,7 +37,7 @@ module OpenNebulaJSON template = template_to_str(image_hash) end - self.allocate(template,ds_id) + self.allocate(template,ds_id.to_i) end def perform_action(template_json) diff --git a/src/sunstone/models/SunstoneServer.rb b/src/sunstone/models/SunstoneServer.rb index fba385ec96..2739d9b2b4 100644 --- a/src/sunstone/models/SunstoneServer.rb +++ b/src/sunstone/models/SunstoneServer.rb @@ -130,9 +130,22 @@ class SunstoneServer < CloudServer ############################################################################ def upload(template, file_path) image_hash = parse_json(template, 'image') + if OpenNebula.is_error?(image_hash) + return [500, image_hash.to_json] + end + image_hash['PATH'] = file_path - new_template = {:image => image_hash}.to_json + ds_id = parse_json(template, 'ds_id') + if OpenNebula.is_error?(ds_id) + return [500, ds_id.to_json] + end + + new_template = { + :image => image_hash, + :ds_id => ds_id, + }.to_json + image = ImageJSON.new(Image.build_xml, @client) rc = image.create(new_template) diff --git a/src/sunstone/public/js/plugins/dashboard-tab.js b/src/sunstone/public/js/plugins/dashboard-tab.js index 362c51e347..06b931244b 100644 --- a/src/sunstone/public/js/plugins/dashboard-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-tab.js @@ -58,6 +58,10 @@ var dashboard_tab_content = ' + tr("Hosts (total/active)") + '\ \ \ + \ + ' + tr("Clusters") + '\ + \ + \ \ ' + tr("Groups") + '\ \ @@ -78,6 +82,10 @@ var dashboard_tab_content = ' + tr("Virtual Networks (total/public)") + '\ \ \ + \ + ' + tr("Datastores") + '\ + \ + \ \ ' + tr("Images (total/public)") + '\ \ @@ -102,11 +110,13 @@ var dashboard_tab_content =

' + tr("Quickstart") + '

\
\ \ \ \ + \ + \ + \ + \ \ \ \ @@ -85,7 +89,7 @@ var dashboard_tab_content =

'+tr("Quickstart")+'

\
\
\ -\ +\ ' + tr("Host") + '
\ + ' + tr("Cluster") + '
\ ' + tr("VM Instance") + '
\ ' + tr("VM Template") + '
\ - ' + tr("Virtual Network") + '
\ + ' + tr("Virtual Network") + '
\ + ' + tr("Datastore") + '
\ ' + tr("Image") + '
\ ' + tr("User") + '
\ ' + tr("Group") + '
\ @@ -316,5 +326,13 @@ function updateDashboard(what,json_info){ var total_acls=json_info.length; $('#total_acls',db).html(total_acls); break; + case "clusters": + var total_clusters=json_info.length; + $('#total_clusters',db).html(total_clusters); + break; + case "datastores": + var total_datastores=json_info.length; + $('#total_datastores',db).html(total_datastores); + break; } } diff --git a/src/sunstone/public/js/plugins/dashboard-users-tab.js b/src/sunstone/public/js/plugins/dashboard-users-tab.js index 4e602814be..f27ed855fb 100644 --- a/src/sunstone/public/js/plugins/dashboard-users-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-users-tab.js @@ -69,6 +69,10 @@ var dashboard_tab_content =
'+tr("Virtual Networks (total/public)")+'
' + tr("Datastores") + '
'+tr("Images (total/public)")+'
\ - \ + \ '+tr("VM Template")+'
\ '+tr("VM Instance")+'
\ '+tr("Virtual Network")+'
\ @@ -296,5 +300,13 @@ function updateDashboard(what,json_info){ var total_acls=json_info.length; $('#total_acls',db).html(total_acls); break; + case "clusters": + var total_clusters=json_info.length; + $('#total_clusters',db).html(total_clusters); + break; + case "datastores": + var total_datastores=json_info.length; + $('#total_datastores',db).html(total_datastores); + break; } } \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/datastores-tab.js b/src/sunstone/public/js/plugins/datastores-tab.js index 603fd6867e..88afb16aab 100644 --- a/src/sunstone/public/js/plugins/datastores-tab.js +++ b/src/sunstone/public/js/plugins/datastores-tab.js @@ -265,7 +265,8 @@ var datastore_buttons = { }, "Datastore.create_dialog" : { type: "create_dialog", - text: tr("+ New") + text: tr("+ New"), + condition: mustBeAdmin, }, "Datastore.update_dialog" : { type: "action", @@ -277,6 +278,7 @@ var datastore_buttons = { text: tr("Select cluster"), select: clusters_sel, tip: tr("Select the destination cluster:"), + condition: mustBeAdmin, }, "Datastore.chown" : { type: "confirm_with_select", @@ -354,22 +356,34 @@ function datastoreInfoListener(){ Sunstone.runAction("Datastore.showinfo",id); return false; }); -} +}; + +function updateDatastoreSelect(){ + datastores_select = makeSelectOptions(dataTable_datastores, + 1, + 4, + [], + [] + ); +}; function updateDatastoreElement(request, element_json){ var id = element_json.DATASTORE.ID; var element = datastoreElementArray(element_json); updateSingleElement(element,dataTable_datastores,'#datastore_'+id) + updateDatastoreSelect(); } function deleteDatastoreElement(request){ deleteElement(dataTable_datastores,'#datastore_'+request.request.data); + updateDatastoreSelect(); } function addDatastoreElement(request,element_json){ var id = element_json.DATASTORE.ID; var element = datastoreElementArray(element_json); addElement(element,dataTable_datastores); + updateDatastoreSelect(); } @@ -381,17 +395,28 @@ function updateDatastoresView(request, list){ }); updateView(list_array,dataTable_datastores); + updateDatastoreSelect(); updateDashboard("datastores",list); } function updateDatastoreInfo(request,ds){ var info = ds.DATASTORE; + var images_str = ""; + if (info.IMAGES.ID && + info.IMAGES.ID.constructor == Array){ + for (var i=0; i\ + '\ \ \ \ @@ -428,6 +453,10 @@ function updateDatastoreInfo(request,ds){ \ \ \ + \ + \ + \ + \ \ \ \ diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index ad8d818883..ca5dd57182 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -63,6 +63,12 @@ var create_image_tmpl = \
'+tr("Human readable description of the image for other users.")+'
\ \ +
\ + \ + \ +
'+tr("Select the datastore for this image")+'
\ +
\ \
\
\ @@ -850,7 +856,11 @@ function setupCreateImageDialog(){ }); if (exit) { return false; } - var ds_id = $('#img_ds_id',this).val(); + var ds_id = $('#img_datastore',this).val(); + if (!ds_id){ + notifyError(tr("Please select a datastore for this image")); + return false; + }; var img_json = {}; @@ -906,7 +916,6 @@ function setupCreateImageDialog(){ img_json[attr_name] = attr_value; }); - ds_id = 1; img_obj = { "image" : img_json, "ds_id" : ds_id}; @@ -932,6 +941,8 @@ function popUpCreateImageDialog(){ $('#file-uploader input',$create_image_dialog).removeAttr("style"); $('#file-uploader input',$create_image_dialog).attr('style','margin:0;width:256px!important'); + $('#img_datastore',$create_image_dialog).html(datastores_sel()); + $create_image_dialog.dialog('open'); } diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index b9b63a21b7..f1865b92dc 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -419,6 +419,7 @@ var vnet_buttons = { text: tr("Select cluster"), select: clusters_sel, tip: tr("Select the destination cluster:"), + condition: mustBeAdmin, }, "Network.chown" : { type: "confirm_with_select", diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js index 02a060b5d3..4b16656250 100644 --- a/src/sunstone/public/js/sunstone-util.js +++ b/src/sunstone/public/js/sunstone-util.js @@ -403,19 +403,26 @@ function waitingNodes(dataTable){ function getUserName(uid){ if (typeof(dataTable_users) != "undefined"){ - return getName(uid,dataTable_users); + return getName(uid,dataTable_users,2); } return uid; } function getGroupName(gid){ if (typeof(dataTable_groups) != "undefined"){ - return getName(gid,dataTable_groups); + return getName(gid,dataTable_groups,2); } return gid; } -function getName(id,dataTable){ +function getImageName(id){ + if (typeof(dataTable_images) != "undefined"){ + return getName(id,dataTable_images,4); + } + return id; +}; + +function getName(id,dataTable,name_col){ var name = id; if (typeof(dataTable) == "undefined") { return name; @@ -424,7 +431,7 @@ function getName(id,dataTable){ $.each(nodes,function(){ if (id == this[1]) { - name = this[2]; + name = this[name_col]; return false; } }); @@ -755,6 +762,10 @@ function clusters_sel() { return clusters_select; } +function datastores_sel() { + return datastores_select; +} + function ownerUse(resource){ From 5178369f0a3683110ef56ba9ca4f574902fefedb Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 12 Mar 2012 16:27:51 +0100 Subject: [PATCH 2/5] Feature #1112: Support improved submenus and menu expansion --- src/sunstone/public/css/layout.css | 16 +++++++--- src/sunstone/public/js/layout.js | 49 +++++++++++++++++++----------- src/sunstone/public/js/sunstone.js | 7 ++++- src/sunstone/views/index.erb | 2 +- 4 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/sunstone/public/css/layout.css b/src/sunstone/public/css/layout.css index f7b14cf703..6bf81da6ed 100644 --- a/src/sunstone/public/css/layout.css +++ b/src/sunstone/public/css/layout.css @@ -120,15 +120,23 @@ background-image: -moz-linear-gradient( rgb(53,55,53) 100% ); } -#navigation { + +.navigation { list-style: none; padding: 0; } -#navigation li { +.navigation li.topTab { line-height: 2em; - text-align: right; - padding-right: 10px; + text-align: left; + padding-left: 15px; +} + +.navigation li.subTab { + line-height: 1.8em; + font-size: 12px; + text-align: left; + padding-left: 30px; } #navigation li a { diff --git a/src/sunstone/public/js/layout.js b/src/sunstone/public/js/layout.js index b783835236..b0489446bc 100644 --- a/src/sunstone/public/js/layout.js +++ b/src/sunstone/public/js/layout.js @@ -48,28 +48,44 @@ function showTab(tabname){ $(".tab").hide(); $(activeTab).show(); //~ if (activeTab == '#dashboard') { - //~ emptyDashboard(); - //~ preloadTables(); - //~ } + //~ emptyDashboard(); + //~ preloadTables(); + //~ } innerLayout.close("south"); } +function setupTabs(){ + + var topTabs = $(".outer-west ul li.topTab"); + var subTabs = $(".outer-west ul li.subTab"); + + subTabs.live("click",function(){ + var tab = $('a',this).attr('href'); + showTab(tab); + return false; + }); + + topTabs.live("click",function(e){ + var tab = $('a',this).attr('href'); + //toggle subtabs trick + if ($(e.target).is('span')){ + $('li.'+tab.substr(1)).fadeToggle('fast'); + $('span',this).toggleClass('ui-icon-circle-plus ui-icon-circle-minus'); + return false; + } else if ($(this).hasClass("navigation-active-li")){//duplicate + $('li.'+tab.substr(1)).fadeToggle('fast'); + $('span',this).toggleClass('ui-icon-circle-plus ui-icon-circle-minus'); + }; + showTab(tab); + return false; + }); + +}; + $(document).ready(function () { $(".tab").hide(); - $(".outer-west ul li.subTab").live("click",function(){ - var tab = $('a',this).attr('href'); - showTab(tab); - return false; - }); - - $(".outer-west ul li.topTab").live("click",function(){ - var tab = $('a',this).attr('href'); - //toggle subtabs trick - $('li.'+tab.substr(1)).toggle(); - showTab(tab); - return false; - }); + setupTabs(); outerLayout = $('body').layout({ applyDefaultStyles: false @@ -106,4 +122,3 @@ $(document).ready(function () { }); }); - diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index 73cb79fd84..6edbc35447 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -470,7 +470,12 @@ function insertTab(tab_name){ $('div#'+tab_name,main_tabs_context).html(tab_info.content); - $('div#menu ul#navigation').append('
  • '+tab_info.title+'
  • '); + $('div#menu ul#navigation').append('
  • '+tab_info.title+'
  • '); + + if (parent){ //this is a subtab + $('div#menu li#li_'+tab_name).hide();//hide by default + $('div#menu li#li_'+parent+' span').css("display","inline-block"); + }; } function hideSubTabs(){ diff --git a/src/sunstone/views/index.erb b/src/sunstone/views/index.erb index 45f277b48c..bca3dc5a1f 100644 --- a/src/sunstone/views/index.erb +++ b/src/sunstone/views/index.erb @@ -58,7 +58,7 @@
    From 51ed17ea0d747ba913c9e4c63e792101f32afd76 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 14 Mar 2012 16:15:05 +0100 Subject: [PATCH 3/5] Feature #1112: Implement cluster menus and submenus. Insert new dashboards. Implement top menu. --- install.sh | 2 + src/sunstone/etc/sunstone-plugins.yaml | 64 +++-- src/sunstone/public/css/application.css | 26 +- src/sunstone/public/css/layout.css | 73 ++++++ src/sunstone/public/js/layout.js | 65 +++-- src/sunstone/public/js/plugins/acls-tab.js | 5 +- .../public/js/plugins/clusters-tab.js | 233 +++++++++++++++++- src/sunstone/public/js/plugins/config-tab.js | 6 +- .../public/js/plugins/dashboard-tab.js | 87 +++---- .../public/js/plugins/dashboard-users-tab.js | 69 ++---- .../public/js/plugins/datastores-tab.js | 8 +- src/sunstone/public/js/plugins/groups-tab.js | 7 +- src/sunstone/public/js/plugins/hosts-tab.js | 10 +- src/sunstone/public/js/plugins/images-tab.js | 5 +- src/sunstone/public/js/plugins/system-tab.js | 113 +++++++++ .../public/js/plugins/templates-tab.js | 6 +- src/sunstone/public/js/plugins/users-tab.js | 7 +- src/sunstone/public/js/plugins/vms-tab.js | 5 +- src/sunstone/public/js/plugins/vnets-tab.js | 8 +- .../public/js/plugins/vresources-tab.js | 137 ++++++++++ src/sunstone/public/js/sunstone-util.js | 28 +++ src/sunstone/public/js/sunstone.js | 27 +- src/sunstone/views/index.erb | 9 + 23 files changed, 819 insertions(+), 181 deletions(-) create mode 100644 src/sunstone/public/js/plugins/system-tab.js create mode 100644 src/sunstone/public/js/plugins/vresources-tab.js diff --git a/install.sh b/install.sh index d5de5583f0..028efd1f0b 100755 --- a/install.sh +++ b/install.sh @@ -1139,6 +1139,8 @@ SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\ src/sunstone/public/js/plugins/hosts-tab.js \ src/sunstone/public/js/plugins/clusters-tab.js \ src/sunstone/public/js/plugins/datastores-tab.js \ + src/sunstone/public/js/plugins/system-tab.js \ + src/sunstone/public/js/plugins/vresources-tab.js \ src/sunstone/public/js/plugins/groups-tab.js \ src/sunstone/public/js/plugins/images-tab.js \ src/sunstone/public/js/plugins/templates-tab.js \ diff --git a/src/sunstone/etc/sunstone-plugins.yaml b/src/sunstone/etc/sunstone-plugins.yaml index ff4d2aaac3..6ae31242a4 100644 --- a/src/sunstone/etc/sunstone-plugins.yaml +++ b/src/sunstone/etc/sunstone-plugins.yaml @@ -9,36 +9,15 @@ :user: :group: oneadmin: false -- plugins/hosts-tab.js: +- plugins/config-tab.js: + :ALL: true + :user: + :group: +- plugins/system-tab.js: :ALL: false :user: :group: oneadmin: true -- plugins/clusters-tab.js: - :ALL: false - :user: - :group: - oneadmin: true -- plugins/vms-tab.js: - :ALL: true - :user: - :group: -- plugins/datastores-tab.js: - :ALL: true - :user: - :group: -- plugins/templates-tab.js: - :ALL: true - :user: - :group: -- plugins/vnets-tab.js: - :ALL: true - :user: - :group: -- plugins/images-tab.js: - :ALL: true - :user: - :group: - plugins/users-tab.js: :ALL: false :user: @@ -54,7 +33,38 @@ :user: :group: oneadmin: true -- plugins/config-tab.js: +- plugins/vresources-tab.js: :ALL: true :user: :group: +- plugins/vms-tab.js: + :ALL: true + :user: + :group: +- plugins/templates-tab.js: + :ALL: true + :user: + :group: +- plugins/images-tab.js: + :ALL: true + :user: + :group: +- plugins/hosts-tab.js: + :ALL: false + :user: + :group: + oneadmin: true +- plugins/datastores-tab.js: + :ALL: true + :user: + :group: +- plugins/vnets-tab.js: + :ALL: true + :user: + :group: +- plugins/clusters-tab.js: + :ALL: false + :user: + :group: + oneadmin: true + diff --git a/src/sunstone/public/css/application.css b/src/sunstone/public/css/application.css index 2f4bbcc15b..c4fca87454 100644 --- a/src/sunstone/public/css/application.css +++ b/src/sunstone/public/css/application.css @@ -31,6 +31,11 @@ select, button { padding: 2px; } +.inline-icon { + display:inline-block; + vertical-align:middle; +} + h2 { float:left; font-size:20px; @@ -46,19 +51,34 @@ h3 { margin: 0 0; } -table#dashboard_table{ +table.dashboard_table{ width:100%; margin: 0; } -table#dashboard_table tr { +table.dashboard_table tr { vertical-align: top; } -table#dashboard_table > tbody > tr > td{ +table.dashboard_table > tbody > tr > td{ width:50%; } +table.dashboard_table .inline-icon { + margin-left: 40px; +} + + +.dashboard_p { + color: #353735; + text-align:justify; +} + + +.clusterElemLi { + list-style: circle; +} + div.panel { background-color: #ffffff; padding:0; diff --git a/src/sunstone/public/css/layout.css b/src/sunstone/public/css/layout.css index 6bf81da6ed..142047d310 100644 --- a/src/sunstone/public/css/layout.css +++ b/src/sunstone/public/css/layout.css @@ -38,6 +38,10 @@ body { padding: 5px 10px 0 10px; } +.hidden { + display:none; +} + body { font-family: Arial, Verdana, Geneva, Helvetica, sans-serif; font-size: 13px; @@ -139,6 +143,29 @@ background-image: -moz-linear-gradient( padding-left: 30px; } +.navigation li.subsubTab { + line-height: 1.7em; + font-size: 11px; + text-align: left; + padding-left: 40px; + +} + +.navigation li.topTab span.plusIcon, +.navigation li.subTab span.plusIcon { + display : none; + float: right; + margin-right: 1em; +} + +.navigation li.topTab span.plusIcon { + margin-top: 5px; +} + +.navigation li.subTab span.plusIcon { + margin-top: 3px; +} + #navigation li a { color: #ffffff; } @@ -177,3 +204,49 @@ background-image: -moz-linear-gradient( #navigation li:hover a, .navigation-active-li-a { color: #ffffff !important; } + + +/* top menu css */ +#menutop_container{ + margin:0px 171px; + color:#FFFFFF; + font-size:13px; + font-weight:bold; +} +#menutop_navbar{ + float:left; + height:25px; + font-size:13px; +} +#menutop_navbar ul{ + float:left; + height:25px; + color:#000000; + margin: 0 0; + padding-left: 1px; +} +#menutop_navbar ul{ + background-color: #353735; +} +#menutop_navbar ul li{ + float:left; + min-width:72px; + margin:0px 0 0 0; + height:22px; + display: inline; + text-align:center; + padding-left:5px; + padding-right: 5px; + padding-top: 4px; + padding-bottom: 4px; + border-left:1px solid white; + cursor:pointer; + color: white; +} + +#menutop_navbar ul li:hover { + background-color: #E69138; + +} + +/* end top menu css */ \ No newline at end of file diff --git a/src/sunstone/public/js/layout.js b/src/sunstone/public/js/layout.js index b0489446bc..54b7bcb06f 100644 --- a/src/sunstone/public/js/layout.js +++ b/src/sunstone/public/js/layout.js @@ -31,19 +31,27 @@ function popDialogLoading(){ popDialog(loading); } -function showTab(tabname){ - activeTab = tabname; +function showTab(tabname,highlight_tab){ + var activeTab = tabname; + + if (!highlight_tab) highlight_tab = activeTab; //clean selected menu $("#navigation li").removeClass("navigation-active-li"); $("#navigation li a").removeClass("navigation-active-li-a"); + $("div#header ul#menutop_ul li").removeClass("navigation-active-li"); - //select menu - var li = $("#navigation li:has(a[href='"+activeTab+"'])") - var li_a = $("#navigation li a[href='"+activeTab+"']") + //select tab in left menu + var li = $("#navigation li:has(a[href='"+highlight_tab+"'])") + var li_a = $("#navigation li a[href='"+highlight_tab+"']") li.addClass("navigation-active-li"); li_a.addClass("navigation-active-li-a"); + //select tab in top menu + var top_li = $("div#header ul#menutop_ul li#top_"+highlight_tab.substring(1)); + top_li.addClass("navigation-active-li"); + + //show tab $(".tab").hide(); $(activeTab).show(); @@ -60,38 +68,67 @@ function setupTabs(){ var subTabs = $(".outer-west ul li.subTab"); subTabs.live("click",function(){ + //leave floor to topTab listener in case of tabs with both classes + if ($(this).hasClass('topTab')) return false; + var tab = $('a',this).attr('href'); showTab(tab); return false; }); topTabs.live("click",function(e){ - var tab = $('a',this).attr('href'); - //toggle subtabs trick - if ($(e.target).is('span')){ - $('li.'+tab.substr(1)).fadeToggle('fast'); - $('span',this).toggleClass('ui-icon-circle-plus ui-icon-circle-minus'); - return false; - } else if ($(this).hasClass("navigation-active-li")){//duplicate - $('li.'+tab.substr(1)).fadeToggle('fast'); + var tab = $('a',this).attr('href'); //This tabs #name + //Subtabs have a class with the name of this tab + var subtabs = $('div#menu li.'+tab.substr(1)); + + //toggle subtabs only when clicking on the icon or when clicking on an + //already selected menu + if ($(e.target).is('span') || + $(this).hasClass("navigation-active-li")){ + //for each subtab, we hide the subsubtabs + subtabs.each(function(){ + //for each subtab, hide its subtabs + var subsubtabs = $('a',this); + //subsubtabs class + subsubtabs = subsubtabs.attr('href').substr(1); + subsubtabs = $('div#menu li.'+subsubtabs); + subsubtabs.hide(); + }); + //hide subtabs and reset icon to + position, since all subsubtabs + //are hidden + subtabs.fadeToggle('fast'); + $('span',subtabs).removeClass('ui-icon-circle-minus'); + $('span',subtabs).addClass('ui-icon-circle-plus'); + //toggle icon on this tab $('span',this).toggleClass('ui-icon-circle-plus ui-icon-circle-minus'); }; + //if we are clicking on the icon only, do not show the tab + if ($(e.target).is('span')) return false; + showTab(tab); return false; }); }; +function setupTopMenu(){ + $('div#header ul#menutop_ul li').live('click',function(){ + var tab = "#" + $(this).attr('id').substring(4); + showTab(tab); + }); +}; + $(document).ready(function () { $(".tab").hide(); setupTabs(); + setupTopMenu(); outerLayout = $('body').layout({ applyDefaultStyles: false , center__paneSelector: ".outer-center" , west__paneSelector: ".outer-west" - , west__size: 133 + , west__size: 181 , north__size: 26 , south__size: 26 , spacing_open: 0 // ALL panes diff --git a/src/sunstone/public/js/plugins/acls-tab.js b/src/sunstone/public/js/plugins/acls-tab.js index 8688c3be92..6a78b08d4f 100644 --- a/src/sunstone/public/js/plugins/acls-tab.js +++ b/src/sunstone/public/js/plugins/acls-tab.js @@ -156,7 +156,9 @@ var acl_buttons = { var acls_tab = { title: tr("ACLs"), content: acls_tab_content, - buttons: acl_buttons + buttons: acl_buttons, + tabClass: 'subTab', + parentTab: 'system_tab' } Sunstone.addActions(acl_actions); @@ -303,6 +305,7 @@ function updateAclsView(request,list){ }); updateView(list_array,dataTable_acls); updateDashboard("acls",list); + updateSystemDashboard("acls",list); } function setupCreateAclDialog(){ diff --git a/src/sunstone/public/js/plugins/clusters-tab.js b/src/sunstone/public/js/plugins/clusters-tab.js index 0a9a90c52a..405353ebbd 100644 --- a/src/sunstone/public/js/plugins/clusters-tab.js +++ b/src/sunstone/public/js/plugins/clusters-tab.js @@ -212,7 +212,8 @@ var host_info_panel = { var clusters_tab = { title: tr("Clusters"), content: clusters_tab_content, - buttons: cluster_buttons + buttons: cluster_buttons, + showOnTopMenu: true, } Sunstone.addActions(cluster_actions); @@ -296,11 +297,232 @@ function updateClustersView (request,list){ list_array.push(clusterElementArray(this)); }); + removeClusterMenus(); + updateView(list_array,dataTable_clusters); updateClusterSelect(); //dependency with the dashboard plugin updateDashboard("clusters",list); -} + newClusterMenu(list); +}; + + +function clusterTabContent(cluster_json) { + var cluster = cluster_json.CLUSTER; + + var dss_list = '
  • '+tr("No datastores in this cluster")+'
  • '; + if (cluster.DATASTORES.ID && + cluster.DATASTORES.ID.constructor == Array){ + dss_list = ''; + for (var i=0; i'; + }; + } else if (cluster.DATASTORES.ID) + dss_list = '
  • '+cluster.DATASTORES.ID+' - '+getDatastoreName(cluster.DATASTORES.ID)+'
  • '; + + var hosts_list = '
  • '+tr("No hosts in this cluster")+'
  • '; + if (cluster.HOSTS.ID && + cluster.HOSTS.ID.constructor == Array){ + hosts_list = ''; + for (var i=0; i'; + }; + } else if (cluster.HOSTS.ID) + hosts_list = '
  • '+cluster.HOSTS.ID+' - '+getHostName(cluster.HOSTS.ID)+'
  • '; + + var vnets_list = '
  • '+tr("No virtual networks in this cluster")+'
  • '; + if (cluster.VNETS.ID && + cluster.VNETS.ID.constructor == Array){ + vnets_list = ''; + for (var i=0; i'; + }; + } else if (cluster.VNETS.ID) + vnets_list = '
  • '+cluster.VNETS.ID+' - '+getVNetName(cluster.VNETS.ID)+'
  • '; + + var html_code = '\ +
    '+tr("Datastore information")+' - '+info.NAME+'
    '+tr("Base path")+''+info.BASE_PATH+'
    '+tr("Images")+''+images_str+'
    '+tr("Permissions")+'
         '+tr("Owner")+'
    \ +\ +\ +\ +
    \ +\ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Cluster information") + '

    \ +
    \ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
    ' + tr("ID") + ''+cluster.ID+'
    ' + tr("Name") + ''+cluster.NAME+'
    \ +\ +
    \ +
    \ +
    \ +
    \ +

    ' + tr("Hosts in this cluster") + '

    \ +
    \ +\ +
      '+hosts_list+'\ +
    \ +\ +
    \ +
    \ +
    \ +\ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Datastores in this cluster") + '

    \ +
    \ +\ +
      '+dss_list+'\ +
    \ +\ +
    \ +
    \ +
    \ +
    \ +

    ' + tr("Virtual Networks in this cluster") + '

    \ +
    \ +\ +
      '+vnets_list+'\ +
    \ +\ +
    \ +
    \ +
    \ +
    \ +'; + + return html_code; +}; + +function removeClusterMenus(){ + var data = dataTable_clusters.fnGetData(); + + Sunstone.removeMainTab('cluster_vnets_tab_n',true); + Sunstone.removeMainTab('cluster_datastores_tab_n',true); + Sunstone.removeMainTab('cluster_hosts_tab_n',true); + Sunstone.removeMainTab('cluster_tab_n',true); + + for (var i=0; i < data.length; i++){ + var id = data[i][1]; + Sunstone.removeMainTab('cluster_vnets_tab_'+id,true); + Sunstone.removeMainTab('cluster_datastores_tab_'+id,true); + Sunstone.removeMainTab('cluster_hosts_tab_'+id,true); + Sunstone.removeMainTab('cluster_tab_'+id,true); + }; +}; + + +function newClusterMenu(list){ + var cluster_none = { + 'CLUSTER' : { + 'NAME' : 'None', + 'ID' : 'n', + 'DATASTORES' : [], + 'HOSTS' : [], + 'VNETS' : [] + } + }; + + newClusterMenuElement(cluster_none); + + for (var i=0; i < list.length; i++){ + newClusterMenuElement(list[i]); + }; + $('div#menu li#li_clusters_tab span').removeClass('ui-icon-circle-minus'); + $('div#menu li#li_clusters_tab span').addClass('ui-icon-circle-plus'); +}; + +function newClusterMenuElement(element){ + var cluster = element.CLUSTER; + var menu_name = cluster.NAME.length > 10 ? + cluster.NAME.substring(0,9)+'...' : cluster.NAME; + + var menu_cluster = { + title: menu_name + ' (id ' + cluster.ID + ')', + content: clusterTabContent(element), + tabClass: 'topTab subTab', + parentTab: 'clusters_tab' +// buttons: null + }; + + var submenu_hosts = { + title: tr("Hosts"), + content: '', + tabClass: "subTab clusterHosts subsubTab", + parentTab: "cluster_tab_" + cluster.ID + }; + + var submenu_datastores = { + title: tr("Datastores"), + content: '', + tabClass: "subTab clusterDatastores subsubTab", + parentTab: "cluster_tab_" + cluster.ID + }; + + var submenu_vnets = { + title: tr("Virtual Networks"), + content: '', + tabClass: "subTab clusterVnets subsubTab", + parentTab: "cluster_tab_" + cluster.ID + }; + + Sunstone.addMainTab('cluster_tab_'+cluster.ID,menu_cluster,true); + Sunstone.addMainTab('cluster_hosts_tab_'+cluster.ID,submenu_hosts,true); + Sunstone.addMainTab('cluster_datastores_tab_'+cluster.ID,submenu_datastores,true); + Sunstone.addMainTab('cluster_vnets_tab_'+cluster.ID,submenu_vnets,true); +}; + +function clusterSubmenusListeners(){ + //hack the menu selection + $('div#menu li.clusterHosts').live('click',function(){ + var id = $(this).attr('id'); + id = id.split('_'); + id = id[id.length-1]; + dataTable_hosts.fnFilter(getClusterName(id),3,false,true,false,true); + showTab('#hosts_tab',$('a',this).attr('href')); + return false; + }); + + $('div#menu li.clusterDatastores').live('click',function(){ + var id = $(this).attr('id'); + id = id.split('_'); + id = id[id.length-1]; + dataTable_datastores.fnFilter(getClusterName(id),5,false,true,false,true); + showTab('#datastores_tab',$('a',this).attr('href')); + return false; + }); + + $('div#menu li.clusterVnets').live('click',function(){ + var id = $(this).attr('id'); + id = id.split('_'); + id = id[id.length-1]; + dataTable_vNetworks.fnFilter(getClusterName(id),5,false,true,false,true); + showTab('#vnets_tab',$('a',this).attr('href')); + return false; + }); +}; /* //Updates the host info panel tab's content and pops it up @@ -459,9 +681,12 @@ function popUpCreateClusterDialog(){ //Prepares the autorefresh for hosts function setClusterAutorefresh() { setInterval(function(){ + var selected_menu = $('div#menu li.navigation-active-li'); + var inSubMenu = selected_menu.attr('id').indexOf('cluster') > 0; + var checked = $('input.check_item:checked',dataTable_clusters); var filter = $("#datatable_clusters_filter input",dataTable_clusters.parents('#datatable_clusters_wrapper')).attr('value'); - if (!checked.length && !filter.length){ + if (!checked.length && !filter.length && !inSubMenu){ Sunstone.runAction("Cluster.autorefresh"); } },INTERVAL+someTime()); @@ -505,6 +730,8 @@ $(document).ready(function(){ setClusterAutorefresh(); + clusterSubmenusListeners(); + initCheckAllBoxes(dataTable_clusters); tableCheckboxesListener(dataTable_clusters); // clusterInfoListener(); diff --git a/src/sunstone/public/js/plugins/config-tab.js b/src/sunstone/public/js/plugins/config-tab.js index 303961fb60..7b2ec99427 100644 --- a/src/sunstone/public/js/plugins/config-tab.js +++ b/src/sunstone/public/js/plugins/config-tab.js @@ -58,8 +58,10 @@ var config_actions = { var config_tab = { title: tr("Configuration"), - content: config_tab_content -} + content: config_tab_content, + tabClass: "subTab", + parentTab: "dashboard_tab", +}; Sunstone.addActions(config_actions); Sunstone.addMainTab('config_tab',config_tab); diff --git a/src/sunstone/public/js/plugins/dashboard-tab.js b/src/sunstone/public/js/plugins/dashboard-tab.js index 06b931244b..3e06fb4de2 100644 --- a/src/sunstone/public/js/plugins/dashboard-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-tab.js @@ -43,7 +43,7 @@ var graph4 = { }; var dashboard_tab_content = -'\ +'
    \ \
    \ \ @@ -67,28 +67,28 @@ var dashboard_tab_content = \ \ \ - \ - \ + \ + \ \ \ \ \ \ \ - \ - \ + \ + \ \ \ \ \ \ \ - \ - \ + \ + \ \ \ \ @@ -108,20 +108,20 @@ var dashboard_tab_content = \ \ @@ -158,7 +158,8 @@ var dashboard_tab_content = var dashboard_tab = { title: tr("Dashboard"), - content: dashboard_tab_content + content: dashboard_tab_content, + showOnTopMenu: true, } Sunstone.addMainTab('dashboard_tab',dashboard_tab); @@ -209,13 +210,6 @@ function plot_global_graph(data,info){ $.plot($('#'+id+'_graph',context),series,options); } -function quickstart_setup(){ - - $('#dashboard_table #quickstart_form input',main_tabs_context).click(function(){ - Sunstone.runAction($(this).val()); - }); -} - function graph_autorefresh(){ setInterval(function(){ refresh_graphs(); @@ -232,7 +226,7 @@ function refresh_graphs(){ $(document).ready(function(){ //Dashboard link listener - $("#dashboard_table h3 a",main_tabs_context).live("click", function (){ + $("#dashboard_tab h3 a",main_tabs_context).live("click", function (){ var tab = $(this).attr('href'); showTab(tab); return false; @@ -240,8 +234,6 @@ $(document).ready(function(){ emptyDashboard(); - quickstart_setup(); - refresh_graphs(); graph_autorefresh(); @@ -288,14 +280,8 @@ function updateDashboard(what,json_info){ $('#failed_vms',db).html(failed_vms); break; case "vnets": - var public_vnets=0; var total_vnets=json_info.length; - $.each(json_info,function(){ - if (parseInt(this.VNET.PUBLIC)){ - public_vnets++;} - }); - $('#total_vnets',db).html(total_vnets+' / '); - $('#public_vnets',db).html(public_vnets); + $('#total_vnets',db).html(total_vnets); break; case "users": var total_users=json_info.length; @@ -303,24 +289,11 @@ function updateDashboard(what,json_info){ break; case "images": var total_images=json_info.length; - var public_images=0; - $.each(json_info,function(){ - if (parseInt(this.IMAGE.PUBLIC)){ - public_images++;} - }); - $('#total_images',db).html(total_images+' / '); - $('#public_images',db).html(public_images); + $('#total_images',db).html(total_images); break; case "templates": var total_templates=json_info.length; - var public_templates=0; - $.each(json_info,function(){ - if (parseInt(this.VMTEMPLATE.PUBLIC)){ - public_templates++; - } - }); - $('#total_templates',db).html(total_templates+' / '); - $('#public_templates',db).html(public_templates); + $('#total_templates',db).html(total_templates); break; case "acls": var total_acls=json_info.length; @@ -335,4 +308,4 @@ function updateDashboard(what,json_info){ $('#total_datastores',db).html(total_datastores); break; } -} +}; diff --git a/src/sunstone/public/js/plugins/dashboard-users-tab.js b/src/sunstone/public/js/plugins/dashboard-users-tab.js index f27ed855fb..e929667e86 100644 --- a/src/sunstone/public/js/plugins/dashboard-users-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-users-tab.js @@ -43,7 +43,7 @@ var graph4 = { }; var dashboard_tab_content = -'
    ' + tr("VM Templates (total/public)") + '' + tr("VM Templates") + '
    ' + - tr("VM Instances")+ ' (' + + tr("VM Instances")+ ' (' + tr("total") + '/' + - tr("running") + '/' + + tr("running") + '/' + tr("failed") + ')
    ' + tr("Virtual Networks (total/public)") + '' + tr("Virtual Networks") + '
    ' + tr("Datastores") + '
    ' + tr("Images (total/public)") + '' + tr("Images") + '
    ' + tr("Users")+'\
    \

    ' + tr("Quickstart") + '

    \ -
    \ -
    \ -\ - ' + tr("Host") + '
    \ - ' + tr("Cluster") + '
    \ - ' + tr("VM Instance") + '
    \ - ' + tr("VM Template") + '
    \ - ' + tr("Virtual Network") + '
    \ - ' + tr("Datastore") + '
    \ - ' + tr("Image") + '
    \ - ' + tr("User") + '
    \ - ' + tr("Group") + '
    \ - ' + tr("Acl") + '
    \ -
    \ + \
    \
    \ +'
    \ \ \ \ @@ -131,7 +131,8 @@ var dashboard_tab_content = var dashboard_tab = { title: tr("Dashboard"), - content: dashboard_tab_content + content: dashboard_tab_content, + showOnTopMenu: true, } Sunstone.addMainTab('dashboard_tab',dashboard_tab); @@ -183,13 +184,6 @@ function plot_global_graph(data,info){ $.plot($('#'+id+'_graph',context),series,options); } -function quickstart_setup(){ - - $('#dashboard_table #quickstart_form input',main_tabs_context).click(function(){ - Sunstone.runAction($(this).val()); - }); -} - function graph_autorefresh(){ setInterval(function(){ refresh_graphs(); @@ -214,8 +208,6 @@ $(document).ready(function(){ emptyDashboard(); - quickstart_setup(); - refresh_graphs(); graph_autorefresh(); @@ -262,14 +254,8 @@ function updateDashboard(what,json_info){ $('#failed_vms',db).html(failed_vms); break; case "vnets": - var public_vnets=0; var total_vnets=json_info.length; - $.each(json_info,function(){ - if (parseInt(this.VNET.PUBLIC)){ - public_vnets++;} - }); - $('#total_vnets',db).html(total_vnets+' / '); - $('#public_vnets',db).html(public_vnets); + $('#total_vnets',db).html(total_vnets); break; case "users": var total_users=json_info.length; @@ -277,24 +263,11 @@ function updateDashboard(what,json_info){ break; case "images": var total_images=json_info.length; - var public_images=0; - $.each(json_info,function(){ - if (parseInt(this.IMAGE.PUBLIC)){ - public_images++;} - }); - $('#total_images',db).html(total_images+' / '); - $('#public_images',db).html(public_images); + $('#total_images',db).html(total_images); break; case "templates": var total_templates=json_info.length; - var public_templates=0; - $.each(json_info,function(){ - if (parseInt(this.VMTEMPLATE.PUBLIC)){ - public_templates++; - } - }); - $('#total_templates',db).html(total_templates+' / '); - $('#public_templates',db).html(public_templates); + $('#total_templates',db).html(total_templates); break; case "acls": var total_acls=json_info.length; @@ -309,4 +282,4 @@ function updateDashboard(what,json_info){ $('#total_datastores',db).html(total_datastores); break; } -} \ No newline at end of file +}; \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/datastores-tab.js b/src/sunstone/public/js/plugins/datastores-tab.js index 88afb16aab..906508e706 100644 --- a/src/sunstone/public/js/plugins/datastores-tab.js +++ b/src/sunstone/public/js/plugins/datastores-tab.js @@ -314,7 +314,9 @@ var datastore_info_panel = { var datastores_tab = { title: tr("Datastores"), content: datastores_tab_content, - buttons: datastore_buttons + buttons: datastore_buttons, + tabClass: "hidden", + showOnTopMenu: true, } Sunstone.addActions(datastore_actions); @@ -683,4 +685,8 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_datastores); tableCheckboxesListener(dataTable_datastores); datastoreInfoListener(); + + $('div#header ul#menutop_ul li#top_datastores_tab').live('click',function(){ + dataTable_datastores.fnFilter('',5); + }); }) \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/groups-tab.js b/src/sunstone/public/js/plugins/groups-tab.js index 981ed8f3c7..bd267b42e7 100644 --- a/src/sunstone/public/js/plugins/groups-tab.js +++ b/src/sunstone/public/js/plugins/groups-tab.js @@ -142,8 +142,10 @@ var group_buttons = { var groups_tab = { title: tr("Groups"), content: groups_tab_content, - buttons: group_buttons -} + buttons: group_buttons, + tabClass: 'subTab', + parentTab: 'system_tab' +}; Sunstone.addActions(group_actions); Sunstone.addMainTab('groups_tab',groups_tab); @@ -224,6 +226,7 @@ function updateGroupsView(request, group_list){ updateView(group_list_array,dataTable_groups); updateGroupSelect(group_list); updateDashboard("groups",group_list); + updateSystemDashboard("groups",group_list); } //Prepares the dialog to create diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 084434343c..3ada27792f 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -318,8 +318,10 @@ var host_info_panel = { var hosts_tab = { title: tr("Hosts"), content: hosts_tab_content, - buttons: host_buttons -} + buttons: host_buttons, + tabClass: "hidden", + showOnTopMenu: true, +}; Sunstone.addActions(host_actions); Sunstone.addMainTab('hosts_tab',hosts_tab); @@ -665,4 +667,8 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_hosts); tableCheckboxesListener(dataTable_hosts); hostInfoListener(); + + $('div#header ul#menutop_ul li#top_hosts_tab').live('click',function(){ + dataTable_hosts.fnFilter('',3); + }); }); diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index ca5dd57182..5fddb91c4e 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -496,7 +496,9 @@ var image_info_panel = { var images_tab = { title: tr("Images"), content: images_tab_content, - buttons: image_buttons + buttons: image_buttons, + tabClass: 'subTab', + parentTab: 'vres_tab' } Sunstone.addActions(image_actions); @@ -586,6 +588,7 @@ function updateImagesView(request, images_list){ updateView(image_list_array,dataTable_images); updateDashboard("images",images_list); + updateVResDashboard("images",images_list); } // Callback to update the information panel tabs and pop it up diff --git a/src/sunstone/public/js/plugins/system-tab.js b/src/sunstone/public/js/plugins/system-tab.js new file mode 100644 index 0000000000..ac636eb503 --- /dev/null +++ b/src/sunstone/public/js/plugins/system-tab.js @@ -0,0 +1,113 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +var system_tab_content = +'
    \ \ @@ -55,8 +55,8 @@ var dashboard_tab_content = \
    \ \ - \ - \ + \ + \ \ \ \ \ \ - \ - \ + \ + \ \ \ \ \ \ \ - \ - \ + \ + \ \
    '+tr("VM Templates (total/public)")+''+tr("VM Templates")+'
    '+tr("VM Instances")+' ('+ @@ -66,16 +66,16 @@ var dashboard_tab_content =
    '+tr("Virtual Networks (total/public)")+''+tr("Virtual Networks")+'
    ' + tr("Datastores") + '
    '+tr("Images (total/public)")+''+tr("Images")+'
    \ \ @@ -87,14 +87,14 @@ var dashboard_tab_content =
    \
    \

    '+tr("Quickstart")+'

    \ -
    \ -
    \ - \ - '+tr("VM Template")+'
    \ - '+tr("VM Instance")+'
    \ - '+tr("Virtual Network")+'
    \ - '+tr("Image")+'
    \ -
    \ + \
    \
    \ +\ +\ +\ +
    \ +\ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Summary of system resources") + '

    \ +
    \ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
    ' + tr("Groups") + '
    ' + tr("Users")+'
    ' + tr("ACL Rules") + '
    \ +\ +
    \ +
    \ +
    \ +
    \ +

    ' + tr("Quickstart") + '

    \ + \ +
    \ +
    \ +
    \ +\ + \ + \ + \ +
    \ +
    \ +

    ' + tr("System Resources") + '

    \ +
    \ +

    '+tr("System resources management is only accesible to users of the oneadmin group. It comprises the operations regarding OpenNebula groups, users and ACLs.")+'

    \ +

    '+tr("You can find further information on the following links:")+'

    \ + \ +
    \ +
    \ +
    \ +
    '; + +var system_tab = { + title: tr("System"), + content: system_tab_content +} + +Sunstone.addMainTab('system_tab',system_tab); + +function updateSystemDashboard(what, json_info){ + var db = $('#system_tab',main_tabs_context); + switch (what){ + case "groups": + var total_groups=json_info.length; + $('#system_total_groups',db).html(total_groups); + break; + case "users": + var total_users=json_info.length; + $('#system_total_users',db).html(total_users); + break; + case "acls": + var total_acls=json_info.length; + $('#system_total_acls',db).html(total_acls); + break; + }; +} + +$(document).ready(function(){ + +}); \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index f4f1f8a28e..dc9566daa3 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -830,7 +830,9 @@ var template_info_panel = { var templates_tab = { title: tr("Templates"), content: templates_tab_content, - buttons: template_buttons + buttons: template_buttons, + tabClass: 'subTab', + parentTab: 'vres_tab' } Sunstone.addActions(template_actions); @@ -922,7 +924,7 @@ function updateTemplatesView(request, templates_list){ updateView(template_list_array,dataTable_templates); updateTemplateSelect(); updateDashboard("templates",templates_list); - + updateVResDashboard("templates",templates_list); } // Callback to update the information panel tabs and pop it up diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index 19d48435e1..906004e77d 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -306,8 +306,10 @@ var user_info_panel = { var users_tab = { title: tr("Users"), content: users_tab_content, - buttons: user_buttons -} + buttons: user_buttons, + tabClass: 'subTab', + parentTab: 'system_tab' +}; Sunstone.addActions(user_actions); Sunstone.addMainTab('users_tab',users_tab); @@ -383,6 +385,7 @@ function updateUsersView(request,users_list){ }); updateView(user_list_array,dataTable_users); updateDashboard("users",users_list); + updateSystemDashboard("users",users_list); updateUserSelect(); }; diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index ae2364a0e6..ff5815c3fe 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -598,7 +598,9 @@ var vm_info_panel = { var vms_tab = { title: tr("Virtual Machines"), content: vms_tab_content, - buttons: vm_buttons + buttons: vm_buttons, + tabClass: 'subTab', + parentTab: 'vres_tab' } Sunstone.addActions(vm_actions); @@ -700,6 +702,7 @@ function updateVMachinesView(request, vmachine_list){ updateView(vmachine_list_array,dataTable_vMachines); updateDashboard("vms",vmachine_list); + updateVResDashboard("vms",vmachine_list); } diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index f1865b92dc..3716278276 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -457,7 +457,9 @@ var vnet_info_panel = { var vnets_tab = { title: tr("Virtual Networks"), content: vnets_tab_content, - buttons: vnet_buttons + buttons: vnet_buttons, + tabClass: "hidden", + showOnTopMenu: true, } Sunstone.addActions(vnet_actions); @@ -1197,4 +1199,8 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_vNetworks); tableCheckboxesListener(dataTable_vNetworks); vNetworkInfoListener(); + + $('div#header ul#menutop_ul li#top_vnets_tab').live('click',function(){ + dataTable_vNetworks.fnFilter('',5); + }); }); diff --git a/src/sunstone/public/js/plugins/vresources-tab.js b/src/sunstone/public/js/plugins/vresources-tab.js new file mode 100644 index 0000000000..080e933aa0 --- /dev/null +++ b/src/sunstone/public/js/plugins/vresources-tab.js @@ -0,0 +1,137 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +var vres_tab_content = +'\ +\ +\ +\ +
    \ +\ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Summary of virtual resources") + '

    \ +
    \ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +\ + \ + \ + \ +
    ' + tr("VM Templates") + '
    ' + + tr("VM Instances")+ ' (' + + tr("total") + '/' + + tr("running") + '/' + + tr("failed") + ')
    ' + tr("Images") + '
    \ +\ +
    \ +
    \ +
    \ + \ +
    \ +
    \ +\ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Virtual Resources") + '

    \ +
    \ +

    '+tr("The Virtual Resources menu allows management of Virtual Machine Templates, Instances and Images.")+'

    \ +

    '+tr("You can find further information on the following links:")+'

    \ + \ +
    \ +
    \ +
    \ +
    '; + +var vres_tab = { + title: tr("Virtual Resources"), + content: vres_tab_content +} + +Sunstone.addMainTab('vres_tab',vres_tab); + +function updateVResDashboard(what,json_info){ + var db = $('#vres_tab',main_tabs_context); + switch (what){ + case "vms": + var total_vms=json_info.length; + var running_vms=0; + failed_vms=0; + $.each(json_info,function(){ + vm_state = parseInt(this.VM.STATE); + if (vm_state == 3){ + running_vms++; + } + else if (vm_state == 7) { + failed_vms++; + } + }); + $('#vres_total_vms',db).html(total_vms+' / '); + $('#vres_running_vms',db).html(running_vms+' / '); + $('#vres_failed_vms',db).html(failed_vms); + break; + case "vnets": + var total_vnets=json_info.length; + $('#vres_total_vnets',db).html(total_vnets); + break; + case "images": + var total_images=json_info.length; + $('#vres_total_images',db).html(total_images); + break; + case "templates": + var total_templates=json_info.length; + $('#vres_total_templates',db).html(total_templates); + break; + }; +}; + +$(document).ready(function(){ + +}); \ No newline at end of file diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js index 4b16656250..22064569de 100644 --- a/src/sunstone/public/js/sunstone-util.js +++ b/src/sunstone/public/js/sunstone-util.js @@ -422,6 +422,34 @@ function getImageName(id){ return id; }; +function getClusterName(id){ + if (typeof(dataTable_clusters) != "undefined"){ + return getName(id,dataTable_clusters,2); + } + return id; +}; + +function getDatastoreName(id){ + if (typeof(dataTable_datastores) != "undefined"){ + return getName(id,dataTable_datastores,4); + } + return id; +}; + +function getVNetName(id){ + if (typeof(dataTable_vNetworks) != "undefined"){ + return getName(id,dataTable_vNetworks,4); + } + return id; +}; + +function getHostName(id){ + if (typeof(dataTable_hosts) != "undefined"){ + return getName(id,dataTable_hosts,2); + } + return id; +}; + function getName(id,dataTable,name_col){ var name = id; if (typeof(dataTable) == "undefined") { diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index 6edbc35447..b44b45ed76 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -296,7 +296,7 @@ $(document).ready(function(){ //Insert the tabs in the DOM and their buttons. insertTabs(); - //hideSubTabs(); +// hideSubTabs(); insertButtons(); //Enhace the look of select buttons @@ -452,31 +452,30 @@ function insertTabs(){ //adding the content to the proper div and by adding a list item //link to the navigation menu function insertTab(tab_name){ - var tab_info = SunstoneCfg["tabs"][tab_name]; - var condition = tab_info["condition"]; - var tabClass = tab_info["tabClass"]; - var parent = ""; - - if (!tabClass) { - tabClass="topTab"; - } else if (tabClass=="subTab") { - parent = tab_info["parentTab"]; - }; + var tab_info = SunstoneCfg['tabs'][tab_name]; + var condition = tab_info['condition']; + var tabClass = tab_info['tabClass'] ? tab_info['tabClass'] : 'topTab'; + var parent = tab_info['parentTab'] ? tab_info['parentTab'] : ''; + var showOnTop = tab_info['showOnTopMenu']; //skip this tab if we do not meet the condition if (condition && !condition()) {return;} - main_tabs_context.append('
    '); + main_tabs_context.append(''); $('div#'+tab_name,main_tabs_context).html(tab_info.content); - $('div#menu ul#navigation').append('
  • '+tab_info.title+'
  • '); + $('div#menu ul#navigation').append('
  • '+tab_info.title+'
  • '); if (parent){ //this is a subtab $('div#menu li#li_'+tab_name).hide();//hide by default $('div#menu li#li_'+parent+' span').css("display","inline-block"); }; -} + + if (showOnTop){ + $('div#header ul#menutop_ul').append('
  • '+tab_info.title+'
  • '); + }; +}; function hideSubTabs(){ for (tab in SunstoneCfg["tabs"]){ diff --git a/src/sunstone/views/index.erb b/src/sunstone/views/index.erb index bca3dc5a1f..a2ad30582d 100644 --- a/src/sunstone/views/index.erb +++ b/src/sunstone/views/index.erb @@ -66,6 +66,15 @@ + + +
    Welcome  | Sign Out
    From 3506116a5eaade40b240fcaf1044328a55e358a2 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 15 Mar 2012 00:17:51 +0100 Subject: [PATCH 4/5] Feature #1112: Remove links from menu items. No need to use them as the effect is achieved with cursor: pointer; CSS property on
  • items directly. Update necessary sunstone files. --- src/sunstone/public/css/layout.css | 8 ++--- src/sunstone/public/js/layout.js | 30 +++++++++---------- .../public/js/plugins/clusters-tab.js | 6 ++-- .../public/js/plugins/dashboard-tab.js | 7 ----- .../public/js/plugins/dashboard-users-tab.js | 7 ----- src/sunstone/public/js/sunstone.js | 4 +-- 6 files changed, 24 insertions(+), 38 deletions(-) diff --git a/src/sunstone/public/css/layout.css b/src/sunstone/public/css/layout.css index 142047d310..4c28a08978 100644 --- a/src/sunstone/public/css/layout.css +++ b/src/sunstone/public/css/layout.css @@ -148,7 +148,6 @@ background-image: -moz-linear-gradient( font-size: 11px; text-align: left; padding-left: 40px; - } .navigation li.topTab span.plusIcon, @@ -166,8 +165,9 @@ background-image: -moz-linear-gradient( margin-top: 3px; } -#navigation li a { +#navigation li { color: #ffffff; + cursor: pointer; } #navigation li:hover, .navigation-active-li { @@ -198,10 +198,10 @@ background-image: -moz-linear-gradient( ); */ } -.navigation-active-li-a { +.navigation-active-li { font-weight: bold; } -#navigation li:hover a, .navigation-active-li-a { +#navigation li:hover { color: #ffffff !important; } diff --git a/src/sunstone/public/js/layout.js b/src/sunstone/public/js/layout.js index 54b7bcb06f..c655a50b10 100644 --- a/src/sunstone/public/js/layout.js +++ b/src/sunstone/public/js/layout.js @@ -32,33 +32,34 @@ function popDialogLoading(){ } function showTab(tabname,highlight_tab){ + //Since menu items no longer have an element + //we no longer expect #tab_id here, but simply tab_id + //So safety check - remove # from #tab_id if present to ensure compatibility + if (tabname.indexOf('#') == 0) + tabname = tabname.substring(1); + if (highlight_tab && highlight_tab.indexOf('#') == 0) + highlight_tab == highlight.substring(1); + var activeTab = tabname; if (!highlight_tab) highlight_tab = activeTab; //clean selected menu $("#navigation li").removeClass("navigation-active-li"); - $("#navigation li a").removeClass("navigation-active-li-a"); $("div#header ul#menutop_ul li").removeClass("navigation-active-li"); //select tab in left menu - var li = $("#navigation li:has(a[href='"+highlight_tab+"'])") - var li_a = $("#navigation li a[href='"+highlight_tab+"']") + var li = $("#navigation li#li_"+highlight_tab) li.addClass("navigation-active-li"); - li_a.addClass("navigation-active-li-a"); //select tab in top menu - var top_li = $("div#header ul#menutop_ul li#top_"+highlight_tab.substring(1)); + var top_li = $("div#header ul#menutop_ul li#top_"+highlight_tab); top_li.addClass("navigation-active-li"); //show tab $(".tab").hide(); - $(activeTab).show(); - //~ if (activeTab == '#dashboard') { - //~ emptyDashboard(); - //~ preloadTables(); - //~ } + $('#'+activeTab).show(); innerLayout.close("south"); } @@ -71,15 +72,15 @@ function setupTabs(){ //leave floor to topTab listener in case of tabs with both classes if ($(this).hasClass('topTab')) return false; - var tab = $('a',this).attr('href'); + var tab = $(this).attr('id').substring(3); showTab(tab); return false; }); topTabs.live("click",function(e){ - var tab = $('a',this).attr('href'); //This tabs #name + var tab = $(this).attr('id').substring(3); //Subtabs have a class with the name of this tab - var subtabs = $('div#menu li.'+tab.substr(1)); + var subtabs = $('div#menu li.'+tab); //toggle subtabs only when clicking on the icon or when clicking on an //already selected menu @@ -88,9 +89,8 @@ function setupTabs(){ //for each subtab, we hide the subsubtabs subtabs.each(function(){ //for each subtab, hide its subtabs - var subsubtabs = $('a',this); + var subsubtabs = $(this).attr('id').substr(3); //subsubtabs class - subsubtabs = subsubtabs.attr('href').substr(1); subsubtabs = $('div#menu li.'+subsubtabs); subsubtabs.hide(); }); diff --git a/src/sunstone/public/js/plugins/clusters-tab.js b/src/sunstone/public/js/plugins/clusters-tab.js index 405353ebbd..e063f160d3 100644 --- a/src/sunstone/public/js/plugins/clusters-tab.js +++ b/src/sunstone/public/js/plugins/clusters-tab.js @@ -501,7 +501,7 @@ function clusterSubmenusListeners(){ id = id.split('_'); id = id[id.length-1]; dataTable_hosts.fnFilter(getClusterName(id),3,false,true,false,true); - showTab('#hosts_tab',$('a',this).attr('href')); + showTab('#hosts_tab',$(this).attr('id').substring(3)); return false; }); @@ -510,7 +510,7 @@ function clusterSubmenusListeners(){ id = id.split('_'); id = id[id.length-1]; dataTable_datastores.fnFilter(getClusterName(id),5,false,true,false,true); - showTab('#datastores_tab',$('a',this).attr('href')); + showTab('#datastores_tab',$(this).attr('id').substring(3)); return false; }); @@ -519,7 +519,7 @@ function clusterSubmenusListeners(){ id = id.split('_'); id = id[id.length-1]; dataTable_vNetworks.fnFilter(getClusterName(id),5,false,true,false,true); - showTab('#vnets_tab',$('a',this).attr('href')); + showTab('#vnets_tab',$(this).attr('id').substring(3)); return false; }); }; diff --git a/src/sunstone/public/js/plugins/dashboard-tab.js b/src/sunstone/public/js/plugins/dashboard-tab.js index 3e06fb4de2..6549fb56cf 100644 --- a/src/sunstone/public/js/plugins/dashboard-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-tab.js @@ -225,13 +225,6 @@ function refresh_graphs(){ } $(document).ready(function(){ - //Dashboard link listener - $("#dashboard_tab h3 a",main_tabs_context).live("click", function (){ - var tab = $(this).attr('href'); - showTab(tab); - return false; - }); - emptyDashboard(); refresh_graphs(); diff --git a/src/sunstone/public/js/plugins/dashboard-users-tab.js b/src/sunstone/public/js/plugins/dashboard-users-tab.js index e929667e86..fe0bf48c30 100644 --- a/src/sunstone/public/js/plugins/dashboard-users-tab.js +++ b/src/sunstone/public/js/plugins/dashboard-users-tab.js @@ -199,13 +199,6 @@ function refresh_graphs(){ } $(document).ready(function(){ - //Dashboard link listener - $("#dashboard_table h3 a",main_tabs_context).live("click", function (){ - var tab = $(this).attr('href'); - showTab(tab); - return false; - }); - emptyDashboard(); refresh_graphs(); diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index b44b45ed76..df9659a96c 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -373,7 +373,7 @@ $(document).ready(function(){ }); //Start with the dashboard (supposing we have one). - showTab('#dashboard_tab'); + showTab('dashboard_tab'); }); @@ -465,7 +465,7 @@ function insertTab(tab_name){ $('div#'+tab_name,main_tabs_context).html(tab_info.content); - $('div#menu ul#navigation').append('
  • '+tab_info.title+'
  • '); + $('div#menu ul#navigation').append('
  • '+tab_info.title+'
  • '); if (parent){ //this is a subtab $('div#menu li#li_'+tab_name).hide();//hide by default From 7eec9e111139720c1dc2f862ca2c1fe1c2913e29 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 15 Mar 2012 00:20:52 +0100 Subject: [PATCH 5/5] Feature #1112: Fix ozones and SelfService UIs to work with Sunstone latest menus. Since sunstone menus were reworked, some CSS needed to be updated. layout.js file, which is particular to SelfService, was updated to work with latest version of sunstone too. --- src/cloud/occi/lib/ui/public/css/layout.css | 87 ++++++++++++++- src/cloud/occi/lib/ui/public/js/layout.js | 116 +++++++++++++++----- src/ozones/Server/public/css/layout.css | 73 +++++++++++- 3 files changed, 238 insertions(+), 38 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/css/layout.css b/src/cloud/occi/lib/ui/public/css/layout.css index 5fcdfcb292..624e1e39a3 100644 --- a/src/cloud/occi/lib/ui/public/css/layout.css +++ b/src/cloud/occi/lib/ui/public/css/layout.css @@ -125,14 +125,44 @@ background-image: -moz-linear-gradient( padding: 0; } -#navigation li { +.navigation li.topTab { line-height: 2em; - text-align: right; - padding-right: 10px; + text-align: left; + padding-left: 15px; } -#navigation li a { +.navigation li.subTab { + line-height: 1.8em; + font-size: 12px; + text-align: left; + padding-left: 30px; +} + +.navigation li.subsubTab { + line-height: 1.7em; + font-size: 11px; + text-align: left; + padding-left: 40px; +} + +.navigation li.topTab span.plusIcon, +.navigation li.subTab span.plusIcon { + display : none; + float: right; + margin-right: 1em; +} + +.navigation li.topTab span.plusIcon { + margin-top: 5px; +} + +.navigation li.subTab span.plusIcon { + margin-top: 3px; +} + +#navigation li { color: #ffffff; + cursor: pointer; } #navigation li:hover, .navigation-active-li { @@ -163,10 +193,10 @@ background-image: -moz-linear-gradient( ); */ } -.navigation-active-li-a { +.navigation-active-li { font-weight: bold; } -#navigation li:hover a, .navigation-active-li-a { +#navigation li:hover { color: #ffffff !important; } @@ -181,3 +211,48 @@ background-image: -moz-linear-gradient( width: 100px; height: 22px; } + +/* top menu css */ +#menutop_container{ + margin:0px 171px; + color:#FFFFFF; + font-size:13px; + font-weight:bold; +} +#menutop_navbar{ + float:left; + height:25px; + font-size:13px; +} +#menutop_navbar ul{ + float:left; + height:25px; + color:#000000; + margin: 0 0; + padding-left: 1px; +} +#menutop_navbar ul{ + background-color: #353735; +} +#menutop_navbar ul li{ + float:left; + min-width:72px; + margin:0px 0 0 0; + height:22px; + display: inline; + text-align:center; + padding-left:5px; + padding-right: 5px; + padding-top: 4px; + padding-bottom: 4px; + border-left:1px solid white; + cursor:pointer; + color: white; +} + +#menutop_navbar ul li:hover { + background-color: #E69138; + +} + +/* end top menu css */ \ No newline at end of file diff --git a/src/cloud/occi/lib/ui/public/js/layout.js b/src/cloud/occi/lib/ui/public/js/layout.js index 7b315b443c..2fee0f93e9 100644 --- a/src/cloud/occi/lib/ui/public/js/layout.js +++ b/src/cloud/occi/lib/ui/public/js/layout.js @@ -14,16 +14,21 @@ /* limitations under the License. */ /* -------------------------------------------------------------------------- */ +//This file is mostly a copy of layout.js from Sunstone. +//Instead of opening a south panel, it opens an east panel. +//Apart from document.ready() modifications, the rest of different lines are +//makerd with MODIFIED + var activeTab; var outerLayout, innerLayout; function hideDialog(){ - innerLayout.close("east"); + innerLayout.close("east");//MODIFIED } function popDialog(content){ $("#dialog").html(content); - innerLayout.open("east"); + innerLayout.open("east");//MODIFIED } function popDialogLoading(){ @@ -31,45 +36,98 @@ function popDialogLoading(){ popDialog(loading); } -function showTab(tabname){ - activeTab = tabname; +function showTab(tabname,highlight_tab){ + //Since menu items no longer have an element + //we no longer expect #tab_id here, but simply tab_id + //So safety check - remove # from #tab_id if present to ensure compatibility + if (tabname.indexOf('#') == 0) + tabname = tabname.substring(1); + if (highlight_tab && highlight_tab.indexOf('#') == 0) + highlight_tab == highlight.substring(1); + + var activeTab = tabname; + + if (!highlight_tab) highlight_tab = activeTab; //clean selected menu $("#navigation li").removeClass("navigation-active-li"); - $("#navigation li a").removeClass("navigation-active-li-a"); + $("div#header ul#menutop_ul li").removeClass("navigation-active-li"); - //select menu - var li = $("#navigation li:has(a[href='"+activeTab+"'])") - var li_a = $("#navigation li a[href='"+activeTab+"']") + //select tab in left menu + var li = $("#navigation li#li_"+highlight_tab) li.addClass("navigation-active-li"); - li_a.addClass("navigation-active-li-a"); + + //select tab in top menu + var top_li = $("div#header ul#menutop_ul li#top_"+highlight_tab); + top_li.addClass("navigation-active-li"); + //show tab $(".tab").hide(); - $(activeTab).show(); - //~ if (activeTab == '#dashboard') { - //~ emptyDashboard(); - //~ preloadTables(); - //~ } - innerLayout.close("south"); -} + $('#'+activeTab).show(); +// innerLayout.close("south");//MODIFIED commented +}; + +function setupTabs(){ + + var topTabs = $(".outer-west ul li.topTab"); + var subTabs = $(".outer-west ul li.subTab"); + + subTabs.live("click",function(){ + //leave floor to topTab listener in case of tabs with both classes + if ($(this).hasClass('topTab')) return false; + + var tab = $(this).attr('id').substring(3); + showTab(tab); + return false; + }); + + topTabs.live("click",function(e){ + var tab = $(this).attr('id').substring(3); + //Subtabs have a class with the name of this tab + var subtabs = $('div#menu li.'+tab); + + //toggle subtabs only when clicking on the icon or when clicking on an + //already selected menu + if ($(e.target).is('span') || + $(this).hasClass("navigation-active-li")){ + //for each subtab, we hide the subsubtabs + subtabs.each(function(){ + //for each subtab, hide its subtabs + var subsubtabs = $(this).attr('id').substr(3); + //subsubtabs class + subsubtabs = $('div#menu li.'+subsubtabs); + subsubtabs.hide(); + }); + //hide subtabs and reset icon to + position, since all subsubtabs + //are hidden + subtabs.fadeToggle('fast'); + $('span',subtabs).removeClass('ui-icon-circle-minus'); + $('span',subtabs).addClass('ui-icon-circle-plus'); + //toggle icon on this tab + $('span',this).toggleClass('ui-icon-circle-plus ui-icon-circle-minus'); + }; + //if we are clicking on the icon only, do not show the tab + if ($(e.target).is('span')) return false; + + showTab(tab); + return false; + }); + +}; + +function setupTopMenu(){ + $('div#header ul#menutop_ul li').live('click',function(){ + var tab = "#" + $(this).attr('id').substring(4); + showTab(tab); + }); +}; $(document).ready(function () { $(".tab").hide(); - $(".outer-west ul li.subTab").live("click",function(){ - var tab = $('a',this).attr('href'); - showTab(tab); - return false; - }); - - $(".outer-west ul li.topTab").live("click",function(){ - var tab = $('a',this).attr('href'); - //toggle subtabs trick - $('li.'+tab.substr(1)).toggle(); - showTab(tab); - return false; - }); + setupTabs(); + //setupTopMenu(); outerLayout = $('body').layout({ applyDefaultStyles: false diff --git a/src/ozones/Server/public/css/layout.css b/src/ozones/Server/public/css/layout.css index 99812fc2b0..5a3762eb53 100644 --- a/src/ozones/Server/public/css/layout.css +++ b/src/ozones/Server/public/css/layout.css @@ -136,9 +136,31 @@ background-image: -moz-linear-gradient( padding-left: 30px; } +.navigation li.subsubTab { + line-height: 1.7em; + font-size: 11px; + text-align: left; + padding-left: 40px; +} -.navigation li a { +.navigation li.topTab span.plusIcon, +.navigation li.subTab span.plusIcon { + display : none; + float: right; + margin-right: 1em; +} + +.navigation li.topTab span.plusIcon { + margin-top: 5px; +} + +.navigation li.subTab span.plusIcon { + margin-top: 3px; +} + +.navigation li { color: #ffffff; + cursor: pointer; } .navigation li:hover, .navigation-active-li { @@ -169,9 +191,54 @@ background-image: -moz-linear-gradient( ); */ } -.navigation-active-li-a { +.navigation-active-li { font-weight: bold; } -.navigation li:hover a, .navigation-active-li-a { +.navigation li:hover { color: #ffffff !important; } + +/* top menu css */ +#menutop_container{ + margin:0px 171px; + color:#FFFFFF; + font-size:13px; + font-weight:bold; +} +#menutop_navbar{ + float:left; + height:25px; + font-size:13px; +} +#menutop_navbar ul{ + float:left; + height:25px; + color:#000000; + margin: 0 0; + padding-left: 1px; +} +#menutop_navbar ul{ + background-color: #353735; +} +#menutop_navbar ul li{ + float:left; + min-width:72px; + margin:0px 0 0 0; + height:22px; + display: inline; + text-align:center; + padding-left:5px; + padding-right: 5px; + padding-top: 4px; + padding-bottom: 4px; + border-left:1px solid white; + cursor:pointer; + color: white; +} + +#menutop_navbar ul li:hover { + background-color: #E69138; + +} + +/* end top menu css */ \ No newline at end of file