diff --git a/install.sh b/install.sh index be8f00b846..5db567dd3b 100755 --- a/install.sh +++ b/install.sh @@ -1178,7 +1178,10 @@ SUNSTONE_PUBLIC_CSS_FILES="src/sunstone/public/css/application.css \ SUNSTONE_PUBLIC_VENDOR_DATATABLES="\ src/sunstone/public/vendor/dataTables/jquery.dataTables.min.js \ + src/sunstone/public/vendor/dataTables/ColVis.min.js \ + src/sunstone/public/vendor/dataTables/ColReorderWithResize.js \ src/sunstone/public/vendor/dataTables/demo_table_jui.css \ + src/sunstone/public/vendor/dataTables/ColVis.css \ src/sunstone/public/vendor/dataTables/BSD-LICENSE.txt \ src/sunstone/public/vendor/dataTables/NOTICE" @@ -1188,7 +1191,7 @@ SUNSTONE_PUBLIC_VENDOR_JGROWL="\ src/sunstone/public/vendor/jGrowl/NOTICE" SUNSTONE_PUBLIC_VENDOR_JQUERY="\ - src/sunstone/public/vendor/jQuery/jquery-1.7.1.min.js \ + src/sunstone/public/vendor/jQuery/jquery-1.7.2.min.js \ src/sunstone/public/vendor/jQuery/MIT-LICENSE.txt \ src/sunstone/public/vendor/jQuery/NOTICE" @@ -1253,10 +1256,15 @@ SUNSTONE_PUBLIC_IMAGES_FILES="src/sunstone/public/images/ajax-loader.gif \ src/sunstone/public/images/yellow_bullet.png \ src/sunstone/public/images/green_bullet.png \ src/sunstone/public/images/vnc_off.png \ - src/sunstone/public/images/vnc_on.png" + src/sunstone/public/images/vnc_on.png \ + src/sunstone/public/images/network_icon.png \ + src/sunstone/public/images/system_icon.png \ + src/sunstone/public/images/server_icon.png \ +" SUNSTONE_PUBLIC_LOCALE_EN_US="\ src/sunstone/public/locale/en_US/en_US.js \ +src/sunstone/public/locale/en_US/en_datatable.txt \ " SUNSTONE_PUBLIC_LOCALE_RU=" diff --git a/src/ozones/Server/lib/OZones.rb b/src/ozones/Server/lib/OZones.rb index cd44f87203..d0313ea7d9 100644 --- a/src/ozones/Server/lib/OZones.rb +++ b/src/ozones/Server/lib/OZones.rb @@ -29,6 +29,8 @@ require 'OZones/AggregatedUsers' require 'OZones/AggregatedClusters' require 'OZones/AggregatedDatastores' require 'OZones/AggregatedTemplates' +require 'OZones/AggregatedClusters' +require 'OZones/AggregatedDatastores' require 'openssl' require 'digest/sha1' diff --git a/src/sunstone/public/css/application.css b/src/sunstone/public/css/application.css index c4fca87454..964b4a86f2 100644 --- a/src/sunstone/public/css/application.css +++ b/src/sunstone/public/css/application.css @@ -39,8 +39,13 @@ select, button { h2 { float:left; font-size:20px; - margin-bottom: 5px; - padding-bottom: 0} + margin-bottom: 2px; + margin-top: 8px; + padding-bottom: 2px; + width:400px; + color: #636663; + border-bottom: 3px solid; +} h3 { border-bottom: 1px solid #CCCCCC; @@ -236,6 +241,10 @@ label{ text-align:left; } +.dataTables_wrapper { + min-height: 0; +} + .dataTables_wrapper label { float: none; width: auto; @@ -340,10 +349,12 @@ tr.odd td, tr.even td{ tr.odd:hover{ background-color: #E69138 !important; + cursor: pointer; } tr.even:hover{ background-color: #E69138 !important; + cursor: pointer; } .show_hide label{ @@ -587,4 +598,25 @@ ul.action_list li a:hover{ .ui-layout-resizer-open-hover, /* hover-color to 'resize' */ .ui-layout-resizer-dragging { background: #EEE; +} + +.dataTables_length { + width: auto; +} + +.ColVis { + margin: 0 10px 0 10px; + float: left; +} + +.ColVis_Button { + padding: 5px; + font-size: 1em; +} + +.legend { + color: #636663; + margin-left: 10px; + margin-top: 5px; + font-style: italic; } \ No newline at end of file diff --git a/src/sunstone/public/images/network_icon.png b/src/sunstone/public/images/network_icon.png new file mode 100644 index 0000000000..3f234ac4b9 Binary files /dev/null and b/src/sunstone/public/images/network_icon.png differ diff --git a/src/sunstone/public/images/server_icon.png b/src/sunstone/public/images/server_icon.png new file mode 100644 index 0000000000..265b10e594 Binary files /dev/null and b/src/sunstone/public/images/server_icon.png differ diff --git a/src/sunstone/public/images/system_icon.png b/src/sunstone/public/images/system_icon.png new file mode 100644 index 0000000000..2a55d06ce4 Binary files /dev/null and b/src/sunstone/public/images/system_icon.png differ diff --git a/src/sunstone/public/js/plugins/acls-tab.js b/src/sunstone/public/js/plugins/acls-tab.js index 98045c0e7c..a61ca0082d 100644 --- a/src/sunstone/public/js/plugins/acls-tab.js +++ b/src/sunstone/public/js/plugins/acls-tab.js @@ -18,8 +18,9 @@ var dataTable_acls; var $create_acl_dialog; -var acls_tab_content = -'
\ +var acls_tab_content = '\ +

'+tr("Access Control Lists")+'

\ +\
\
\ \ @@ -31,11 +32,15 @@ var acls_tab_content = \ \ \ + \ \ \ \ \
'+tr("Affected resources")+''+tr("Resource ID / Owned by")+''+tr("Allowed operations")+''+tr("ACL String")+'
\ +

\ +'+tr("This table shows the ACLs rules broken down to easier the reading and meaning of each one. You can show the ACL original string by clicking on Show/Hide columns.")+'\ +

\
'; var create_acl_tmpl = @@ -287,7 +292,8 @@ function aclElementArray(acl_json){ acl_array[0], acl_array[1], acl_array[2], - acl_array[3] + acl_array[3], + acl.STRING ] } @@ -480,12 +486,17 @@ $(document).ready(function(){ dataTable_acls = $("#datatable_acls",main_tabs_context).dataTable({ "bJQueryUI": true, "bSortClasses": false, + "sDom" : '<"H"lfrC>t<"F"ip>', + "oColVis": { + "aiExclude": [ 0 ] + }, "sPaginationType": "full_numbers", "bAutoWidth":false, "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0] }, - { "sWidth": "35px", "aTargets": [1] } + { "sWidth": "35px", "aTargets": [1] }, + { "bVisible": false, "aTargets": [6]} ], "oLanguage": (datatable_lang != "") ? { @@ -495,7 +506,7 @@ $(document).ready(function(){ dataTable_acls.fnClearTable(); addElement([ spinner, - '','','','',''],dataTable_acls); + '','','','','',''],dataTable_acls); Sunstone.runAction("Acl.list"); diff --git a/src/sunstone/public/js/plugins/clusters-tab.js b/src/sunstone/public/js/plugins/clusters-tab.js index 7cb41a21cd..f08e6ab9ad 100644 --- a/src/sunstone/public/js/plugins/clusters-tab.js +++ b/src/sunstone/public/js/plugins/clusters-tab.js @@ -17,15 +17,16 @@ /*Cluster tab plugin*/ -var clusters_tab_content = -'
\ +var clusters_tab_content = '\ +

'+tr("Clusters")+'

\ +\
\
\ \ \ \ \ - \ + \ \ \ \ @@ -771,7 +772,7 @@ function setupCreateClusterDialog(){ dialog.dialog({ autoOpen: false, modal: true, - width: 500 + width: 400 }); $('button',dialog).button(); @@ -831,6 +832,10 @@ $(document).ready(function(){ dataTable_clusters = $("#datatable_clusters",main_tabs_context).dataTable({ "bJQueryUI": true, "bSortClasses": false, + "sDom" : '<"H"lfrC>t<"F"ip>', + "oColVis": { + "aiExclude": [ 0 ] + }, "bAutoWidth":false, "sPaginationType": "full_numbers", "aoColumnDefs": [ diff --git a/src/sunstone/public/js/plugins/config-tab.js b/src/sunstone/public/js/plugins/config-tab.js index 24a568628a..c56e84cd0f 100644 --- a/src/sunstone/public/js/plugins/config-tab.js +++ b/src/sunstone/public/js/plugins/config-tab.js @@ -45,9 +45,13 @@ var config_tab_content = \ \ \ +

\ +'+tr("These options are stored in your OpenNebula user template.")+'\ +

\ \ \ -
' + tr("All") + '' + tr("id") + '' + tr("ID") + '' + tr("Name") + '
'; +\ +'; var config_actions = { "Config.list" : { diff --git a/src/sunstone/public/js/plugins/datastores-tab.js b/src/sunstone/public/js/plugins/datastores-tab.js index ad4ecbdc49..996a85ba3c 100644 --- a/src/sunstone/public/js/plugins/datastores-tab.js +++ b/src/sunstone/public/js/plugins/datastores-tab.js @@ -17,8 +17,9 @@ /*Datastore tab plugin*/ -var datastores_tab_content = -'
\ +var datastores_tab_content = '\ +

'+tr("Datastores")+'

\ +\
\
\ \ @@ -30,6 +31,9 @@ var datastores_tab_content = \ \ \ + \ + \ + \ \ \ \ @@ -345,7 +349,10 @@ function datastoreElementArray(element_json){ element.UNAME, element.GNAME, element.NAME, - element.CLUSTER.length ? element.CLUSTER : "-" + element.CLUSTER.length ? element.CLUSTER : "-", + element.BASE_PATH, + element.TEMPLATE.TM_MAD, + element.TEMPLATE.DS_MAD ]; } @@ -665,13 +672,18 @@ $(document).ready(function(){ dataTable_datastores = $("#datatable_datastores",main_tabs_context).dataTable({ "bJQueryUI": true, "bSortClasses": false, + "sDom" : '<"H"lfrC>t<"F"ip>', + "oColVis": { + "aiExclude": [ 0 ] + }, "sPaginationType": "full_numbers", "bAutoWidth":false, "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0] }, { "sWidth": "35px", "aTargets": [1] }, - { "sWidth": "100px", "aTargets": [2,3,5] } + { "sWidth": "100px", "aTargets": [2,3,5,7,8] }, + { "bVisible": false, "aTargets": [6,7,8] } ], "oLanguage": (datatable_lang != "") ? { @@ -682,7 +694,7 @@ $(document).ready(function(){ dataTable_datastores.fnClearTable(); addElement([ spinner, - '','','','',''],dataTable_datastores); + '','','','','','','',''],dataTable_datastores); Sunstone.runAction("Datastore.list"); setupCreateDatastoreDialog(); diff --git a/src/sunstone/public/js/plugins/groups-tab.js b/src/sunstone/public/js/plugins/groups-tab.js index b1b112a309..5689390462 100644 --- a/src/sunstone/public/js/plugins/groups-tab.js +++ b/src/sunstone/public/js/plugins/groups-tab.js @@ -18,8 +18,9 @@ var groups_select=""; var dataTable_groups; var $create_group_dialog; -var groups_tab_content = -'\ +var groups_tab_content = '\ +

'+tr("Groups")+'

\ +\
\
\
'+tr("Group")+''+tr("Name")+''+tr("Cluster")+''+tr("Basepath")+''+tr("TM MAD")+''+tr("DS MAD")+'
\ @@ -34,6 +35,9 @@ var groups_tab_content = \ \
\ +

\ +'+tr("Tip: Refresh the list if it only shows user ids in the user column.")+'\ +

\
'; var create_group_tmpl = @@ -273,6 +277,7 @@ $(document).ready(function(){ dataTable_groups = $("#datatable_groups",main_tabs_context).dataTable({ "bJQueryUI": true, "bSortClasses": false, + "sDom" : '<"H"lfrC>t<"F"ip>', "sPaginationType": "full_numbers", "bAutoWidth":false, "aoColumnDefs": [ diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 7dd75732b5..1376a8566d 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -33,26 +33,39 @@ var host_graphs = [ ] -var hosts_tab_content = -'
\ +var hosts_tab_content = '\ +

'+tr("Hosts")+'

\ +\
\
\ \ \ \ \ - \ + \ \ \ \ \ \ \ + \ + \ + \ \ \ \ \
' + tr("All") + '' + tr("id") + '' + tr("ID") + '' + tr("Name") + '' + tr("Cluster") + '' + tr("Running VMs") + '' + tr("CPU Use") + '' + tr("Memory use") + '' + tr("Status") + '' + tr("IM MAD") + '' + tr("VM MAD") + '' + tr("Last monitored on") + '
\ +

\ +'+tr("CPU Use is calculated as the maximum between (total CPU - real CPU usage) and (allocated CPU). Real CPU usage is provided by the hosts monitoring driver. Available CPU is calculated using the information from the CPU setting of the VMs running on that host (allocated CPU)")+'\ +

\ +

\ +'+tr("Memory use is calculated according to the information provided by the host monitoring driver.")+'\ +

\ +

\ +'+tr("You can get monitoring graphs by clicking in the desired host and visiting the monitoring information tab. Note that oneacctd must be running for this information to be updated/available.")+'\ +

\
'; var create_host_tmpl = @@ -391,7 +404,11 @@ function hostElementArray(host_json){ host.HOST_SHARE.RUNNING_VMS, //rvm pb_cpu, pb_mem, - OpenNebula.Helper.resource_state("host_simple",host.STATE) ]; + OpenNebula.Helper.resource_state("host_simple",host.STATE), + host.IM_MAD, + host.VM_MAD, + pretty_time(host.LAST_MON_TIME) + ]; } //Listen to clicks on the tds of the tables and shows the info dialogs. @@ -642,14 +659,19 @@ $(document).ready(function(){ dataTable_hosts = $("#datatable_hosts",main_tabs_context).dataTable({ "bJQueryUI": true, "bSortClasses": false, + "sDom" : '<"H"lfrC>t<"F"ip>', + "oColVis": { + "aiExclude": [ 0 ] + }, "bAutoWidth":false, "sPaginationType": "full_numbers", "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0,4] }, { "sWidth": "35px", "aTargets": [1] }, - { "sWidth": "100px", "aTargets": [7,3] }, - { "sWidth": "200px", "aTargets": [5,6] } + { "sWidth": "100px", "aTargets": [7,3,8,9,10] }, + { "sWidth": "200px", "aTargets": [5,6] }, + { "bVisible": false, "aTargets": [8,9,10]} ], "oLanguage": (datatable_lang != "") ? { @@ -661,7 +683,7 @@ $(document).ready(function(){ dataTable_hosts.fnClearTable(); addElement([ spinner, - '','','','','','',''],dataTable_hosts); + '','','','','','','','','',''],dataTable_hosts); Sunstone.runAction("Host.list"); setupCreateHostDialog(); diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index a7d718dfb8..4fe86d4051 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -16,8 +16,9 @@ /*Images tab plugin*/ -var images_tab_content = -'
\ +var images_tab_content = '\ +

'+tr("Images")+'

\ +\
\
\ \ @@ -40,6 +41,9 @@ var images_tab_content = \ \
\ +

\ +'+tr("Size and registration time are hidden colums. Note that persistent images can only be used by 1 VM. To change image datastore, please re-register the image.")+'\ +

\
'; var create_image_tmpl = @@ -1132,13 +1136,18 @@ $(document).ready(function(){ "bJQueryUI": true, "bSortClasses": false, "bAutoWidth":false, + "sDom" : '<"H"lfrC>t<"F"ip>', + "oColVis": { + "aiExclude": [ 0 ] + }, "sPaginationType": "full_numbers", "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0,2,3,9,10] }, { "sWidth": "35px", "aTargets": [1,6,11] }, { "sWidth": "100px", "aTargets": [5,7] }, - { "sWidth": "150px", "aTargets": [8] } + { "sWidth": "150px", "aTargets": [8] }, + { "bVisible": false, "aTargets": [6,8]} ], "oLanguage": (datatable_lang != "") ? { diff --git a/src/sunstone/public/js/plugins/infra-tab.js b/src/sunstone/public/js/plugins/infra-tab.js index 0b52418572..5f4eddadbe 100644 --- a/src/sunstone/public/js/plugins/infra-tab.js +++ b/src/sunstone/public/js/plugins/infra-tab.js @@ -72,12 +72,13 @@ var infra_tab_content =
\

' + tr("Infrastructure resources") + '

\
\ -

'+tr("The Infrastructure menu allows management of Hosts, Datastores, Virtual Networks. Users in the oneadmin group can manage clusters as well.")+'

\ +

network icon'+tr("The Infrastructure menu allows management of Hosts, Datastores, Virtual Networks. Users in the oneadmin group can manage clusters as well.")+'

\

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

\ \
\
\ diff --git a/src/sunstone/public/js/plugins/system-tab.js b/src/sunstone/public/js/plugins/system-tab.js index ac636eb503..7a4636db06 100644 --- a/src/sunstone/public/js/plugins/system-tab.js +++ b/src/sunstone/public/js/plugins/system-tab.js @@ -67,7 +67,7 @@ var system_tab_content =
\

' + 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.")+'

\ +

user'+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:")+'

\
\ @@ -270,8 +275,6 @@ var user_buttons = { return '\ \ \ - \ - \ ' }, tip: tr("Please choose the new type of authentication for the selected users")+":" @@ -329,7 +332,8 @@ function userElementArray(user_json){ user.ID, user.NAME, user.GNAME, - user.AUTH_DRIVER + user.AUTH_DRIVER, + user.GID ] }; @@ -521,12 +525,17 @@ $(document).ready(function(){ "bJQueryUI": true, "bSortClasses": false, "sPaginationType": "full_numbers", + "sDom" : '<"H"lfrC>t<"F"ip>', + "oColVis": { + "aiExclude": [ 0 ] + }, "bAutoWidth":false, "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0] }, - { "sWidth": "35px", "aTargets": [1] }, - { "sWidth": "150px", "aTargets": [4] } + { "sWidth": "35px", "aTargets": [1,5] }, + { "sWidth": "150px", "aTargets": [4] }, + { "bVisible": false, "aTargets": [5]} ], "oLanguage": (datatable_lang != "") ? { @@ -536,7 +545,7 @@ $(document).ready(function(){ dataTable_users.fnClearTable(); addElement([ spinner, - '','','',''],dataTable_users); + '','','','',''],dataTable_users); Sunstone.runAction("User.list"); diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index 17da0972ea..8a936c904a 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -47,8 +47,9 @@ var vm_graphs = [ } ]; -var vms_tab_content = -'
\ +var vms_tab_content = '\ +

'+tr("Virtual Machines")+'

\ +\
\
\ \ @@ -71,6 +72,12 @@ var vms_tab_content = \ \
\ +

\ +'+tr("CPU, Memory and Start time are hidden columns by default. You can get monitoring graphs by clicking on the desired VM and visiting the monitoring information tab (oneacctd needs to be running for this information to be up to date)")+'\ +

\ +

\ +'+tr("VNC console requires previous install of the noVNC addon. Check Sunstone documentation for more information.")+'\ +

\
'; var create_vm_tmpl ='
\ @@ -1306,7 +1313,7 @@ function setupVNC(){ Sunstone.runAction("VM.stopvnc",id); }); - $('.vnc',main_tabs_context).live("click",function(){ + $('.vnc').live("click",function(){ //Which VM is it? var id = $(this).attr('vm_id'); //Set attribute to dialog @@ -1367,6 +1374,10 @@ $(document).ready(function(){ dataTable_vMachines = $("#datatable_vmachines",main_tabs_context).dataTable({ "bJQueryUI": true, + "sDom" : '<"H"lfrC>t<"F"ip>', + "oColVis": { + "aiExclude": [ 0 ] + }, "bSortClasses": false, "sPaginationType": "full_numbers", "bAutoWidth":false, @@ -1375,7 +1386,8 @@ $(document).ready(function(){ { "sWidth": "60px", "aTargets": [0,6,7] }, { "sWidth": "35px", "aTargets": [1,11] }, { "sWidth": "150px", "aTargets": [5,10] }, - { "sWidth": "100px", "aTargets": [2,3,9] } + { "sWidth": "100px", "aTargets": [2,3,9] }, + { "bVisible": false, "aTargets": [6,7,10]} ], "oLanguage": (datatable_lang != "") ? { diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 4f88366054..4b0f497747 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -16,8 +16,9 @@ /*Virtual networks tab plugin*/ -var vnets_tab_content = -'\ +var vnets_tab_content = '\ +

'+tr("Virtual Networks")+'

\ +\
\
\ \ @@ -37,6 +38,9 @@ var vnets_tab_content = \ \
\ +

\ +'+tr("Tip: edit the leases of a network by clicking on one and going to the lease management tab.")+'\ +

\
'; var create_vn_tmpl = @@ -1174,12 +1178,17 @@ $(document).ready(function(){ "bJQueryUI": true, "bSortClasses": false, "bAutoWidth":false, + "sDom" : '<"H"lfrC>t<"F"ip>', + "oColVis": { + "aiExclude": [ 0 ] + }, "sPaginationType": "full_numbers", "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0,6,7,8] }, { "sWidth": "35px", "aTargets": [1] }, - { "sWidth": "100px", "aTargets": [2,3,5] } + { "sWidth": "100px", "aTargets": [2,3,5] }, + { "bVisible": false, "aTargets": [7]} ], "oLanguage": (datatable_lang != "") ? { diff --git a/src/sunstone/public/js/plugins/vresources-tab.js b/src/sunstone/public/js/plugins/vresources-tab.js index 4e78534912..6e3436d551 100644 --- a/src/sunstone/public/js/plugins/vresources-tab.js +++ b/src/sunstone/public/js/plugins/vresources-tab.js @@ -76,7 +76,8 @@ var vres_tab_content =
\

' + tr("Virtual Resources") + '

\
\ -

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

\ +

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

\ +

'+tr("Virtual Machine templates can be instantiated as many times as you want. You can do it from the Templates tab or by creating a new VM in the VM tab. The second method allows you to customize the name and the number of VMs you want to launch.")+'

\

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

\
    \
  • Creating Virtual Machines
  • \ diff --git a/src/sunstone/public/locale/en_US/en_US.js b/src/sunstone/public/locale/en_US/en_US.js index cececf59b5..34ac6881d1 100644 --- a/src/sunstone/public/locale/en_US/en_US.js +++ b/src/sunstone/public/locale/en_US/en_US.js @@ -1,6 +1,6 @@ //Translated by lang="en_US" -datatable_lang="" +datatable_lang="en_datatable.txt" locale={ "802.1Q":"", "Accept (default)":"", diff --git a/src/sunstone/public/locale/en_US/en_datatable.txt b/src/sunstone/public/locale/en_US/en_datatable.txt new file mode 100644 index 0000000000..b3486ec5d9 --- /dev/null +++ b/src/sunstone/public/locale/en_US/en_datatable.txt @@ -0,0 +1,17 @@ +{ + "sProcessing": "Processing...", + "sLengthMenu": "Show _MENU_ entries", + "sZeroRecords": "No matching records found", + "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries", + "sInfoEmpty": "Showing 0 to 0 of 0 entries", + "sInfoFiltered": "(filtered from _MAX_ total entries)", + "sInfoPostFix": "", + "sSearch": "Search:", + "sUrl": "", + "oPaginate": { + "sFirst": "First", + "sPrevious": "Previous", + "sNext": "Next", + "sLast": "Last" + } +} diff --git a/src/sunstone/public/vendor/dataTables/ColReorderWithResize.js b/src/sunstone/public/vendor/dataTables/ColReorderWithResize.js new file mode 100644 index 0000000000..8096aa0a5f --- /dev/null +++ b/src/sunstone/public/vendor/dataTables/ColReorderWithResize.js @@ -0,0 +1,1194 @@ +/* + * File: ColReorderWithResize.js + * Version: 1.0.5 + * CVS: $Id$ + * Description: Controls for column visiblity in DataTables + Columns resizable by user + * Author: Allan Jardine (www.sprymedia.co.uk) + * Author: Christophe Battarel (www.altairis.fr) + * Created: Wed Sep 15 18:23:29 BST 2010 + * Modified: July 2011 by Christophe Battarel - christophe.battarel@altairis.fr (columns resizable) + * Modified: February 2012 by Martin Marchetta - martin.marchetta@gmail.com + * 1. Made the "hot area" for resizing a little wider (it was a little difficult to hit the exact border of a column for resizing) + * 2. Resizing didn't work at all when using scroller (that plugin splits the table into 2 different tables: one for the header and another one for the body, so when you resized the header, the data columns didn't follow) + * 3. Fixed collateral effects of sorting feature + * 4. If sScrollX is enabled (i.e. horizontal scrolling), when resizing a column the width of the other columns is not changed, but the whole + * table is resized to give an Excel-like behavior (good suggestion by Allan) + * Modified: February 2012 by Christophe Battarel - christophe.battarel@altairis.fr (ColReorder v1.0.5 adaptation) + * Language: Javascript + * License: GPL v2 or BSD 3 point style + * Project: DataTables + * Contact: www.sprymedia.co.uk/contact + * + * Copyright 2010-2011 Allan Jardine, all rights reserved. + * + * This source file is free software, under either the GPL v2 license or a + * BSD style license, available at: + * http://datatables.net/license_gpl2 + * http://datatables.net/license_bsd + * + */ + + +(function($, window, document) { + + +/** + * Switch the key value pairing of an index array to be value key (i.e. the old value is now the + * key). For example consider [ 2, 0, 1 ] this would be returned as [ 1, 2, 0 ]. + * @method fnInvertKeyValues + * @param array aIn Array to switch around + * @returns array + */ +function fnInvertKeyValues( aIn ) +{ + var aRet=[]; + for ( var i=0, iLen=aIn.length ; i= iCols ) + { + this.oApi._fnLog( oSettings, 1, "ColReorder 'from' index is out of bounds: "+iFrom ); + return; + } + + if ( iTo < 0 || iTo >= iCols ) + { + this.oApi._fnLog( oSettings, 1, "ColReorder 'to' index is out of bounds: "+iTo ); + return; + } + + /* + * Calculate the new column array index, so we have a mapping between the old and new + */ + var aiMapping = []; + for ( i=0, iLen=iCols ; i this.s.fixed-1 ) + { + this._fnMouseListener( i, this.s.dt.aoColumns[i].nTh ); + } + + /* Mark the original column order for later reference */ + this.s.dt.aoColumns[i]._ColReorder_iOrigCol = i; + } + + /* State saving */ + this.s.dt.oApi._fnCallbackReg( this.s.dt, 'aoStateSaveParams', function (oS, oData) { + that._fnStateSave.call( that, oData ); + }, "ColReorder_State" ); + + /* An initial column order has been specified */ + var aiOrder = null; + if ( typeof this.s.init.aiOrder != 'undefined' ) + { + aiOrder = this.s.init.aiOrder.slice(); + } + + /* State loading, overrides the column order given */ + if ( this.s.dt.oLoadedState && typeof this.s.dt.oLoadedState.ColReorder != 'undefined' && + this.s.dt.oLoadedState.ColReorder.length == this.s.dt.aoColumns.length ) + { + aiOrder = this.s.dt.oLoadedState.ColReorder; + } + + /* If we have an order to apply - do so */ + if ( aiOrder ) + { + /* We might be called during or after the DataTables initialisation. If before, then we need + * to wait until the draw is done, if after, then do what we need to do right away + */ + if ( !that.s.dt._bInitComplete ) + { + var bDone = false; + this.s.dt.aoDrawCallback.push( { + "fn": function () { + if ( !that.s.dt._bInitComplete && !bDone ) + { + bDone = true; + var resort = fnInvertKeyValues( aiOrder ); + that._fnOrderColumns.call( that, resort ); + } + }, + "sName": "ColReorder_Pre" + } ); + } + else + { + var resort = fnInvertKeyValues( aiOrder ); + that._fnOrderColumns.call( that, resort ); + } + } + }, + + + /** + * Set the column order from an array + * @method _fnOrderColumns + * @param array a An array of integers which dictate the column order that should be applied + * @returns void + * @private + */ + "_fnOrderColumns": function ( a ) + { + if ( a.length != this.s.dt.aoColumns.length ) + { + this.s.dt.oInstance.oApi._fnLog( oDTSettings, 1, "ColReorder - array reorder does not "+ + "match known number of columns. Skipping." ); + return; + } + + for ( var i=0, iLen=a.length ; i 0) + this.table_size = $($('div.dataTables_scrollHead', this.s.dt.nTableWrapper)[0].childNodes[0].childNodes[0]).width(); + } + //////////////////// + + /* are we resizing a column ? */ + if (this.dom.resize) { + var nTh = this.s.mouse.resizeElem; + var nThNext = $(nTh).next(); + var moveLength = e.pageX-this.s.mouse.startX; + if (moveLength != 0 && !scrollXEnabled) + $(nThNext).width(this.s.mouse.nextStartWidth - moveLength); + $(nTh).width(this.s.mouse.startWidth + moveLength); + + //Martin Marchetta: Resize the header too (if sScrollX is enabled) + if(scrollXEnabled && $('div.dataTables_scrollHead', this.s.dt.nTableWrapper) != undefined){ + if($('div.dataTables_scrollHead', this.s.dt.nTableWrapper).length > 0) + $($('div.dataTables_scrollHead', this.s.dt.nTableWrapper)[0].childNodes[0].childNodes[0]).width(this.table_size + moveLength); + } + + //////////////////////// + //Martin Marchetta: Fixed col resizing when the scroller is enabled. + var visibleColumnIndex; + //First determine if this plugin is being used along with the smart scroller... + if($('div.dataTables_scrollBody') != null){ + //...if so, when resizing the header, also resize the table's body (when enabling the Scroller, the table's header and + //body are split into different tables, so the column resizing doesn't work anymore) + if($('div.dataTables_scrollBody').length > 0){ + //Since some columns might have been hidden, find the correct one to resize in the table's body + var currentColumnIndex; + visibleColumnIndex = -1; + for(currentColumnIndex=-1; currentColumnIndex < this.s.dt.aoColumns.length-1 && currentColumnIndex != colResized; currentColumnIndex++){ + if(this.s.dt.aoColumns[currentColumnIndex+1].bVisible) + visibleColumnIndex++; + } + + //Get the scroller's div + tableScroller = $('div.dataTables_scrollBody', this.s.dt.nTableWrapper)[0]; + + //Get the table + scrollingTableHead = $(tableScroller)[0].childNodes[0].childNodes[0].childNodes[0]; + + //Resize the columns + if (moveLength != 0 && !scrollXEnabled){ + $($(scrollingTableHead)[0].childNodes[visibleColumnIndex+1]).width(this.s.mouse.nextStartWidth - moveLength); + } + $($(scrollingTableHead)[0].childNodes[visibleColumnIndex]).width(this.s.mouse.startWidth + moveLength); + + //Resize the table too + if(scrollXEnabled) + $($(tableScroller)[0].childNodes[0]).width(this.table_size + moveLength); + } + } + //////////////////////// + + return; + } + else if (this.s.allowReorder) { + if ( this.dom.drag === null ) + { + /* Only create the drag element if the mouse has moved a specific distance from the start + * point - this allows the user to make small mouse movements when sorting and not have a + * possibly confusing drag element showing up + */ + if ( Math.pow( + Math.pow(e.pageX - this.s.mouse.startX, 2) + + Math.pow(e.pageY - this.s.mouse.startY, 2), 0.5 ) < 5 ) + { + return; + } + this._fnCreateDragNode(); + } + + /* Position the element - we respect where in the element the click occured */ + this.dom.drag.style.left = (e.pageX - this.s.mouse.offsetX) + "px"; + this.dom.drag.style.top = (e.pageY - this.s.mouse.offsetY) + "px"; + + /* Based on the current mouse position, calculate where the insert should go */ + var bSet = false; + for ( var i=1, iLen=this.s.aoTargets.length ; i