brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From henev...@apache.org
Subject [41/50] [abbrv] brooklyn-ui git commit: use JSON array for datatables in sensor, activity, and config, so we have more control about when/how they update, esp for adding tasks dynamically (fnAddRow with DOM is incompatible with filtering); table prettifi
Date Mon, 01 Feb 2016 17:52:14 GMT
use JSON array for datatables in sensor, activity, and config,
so we have more control about when/how they update,
esp for adding tasks dynamically (fnAddRow with DOM is incompatible with filtering);
table prettification, and additional (and a bit more standardised) toolbar for the table


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/d3722ad7
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/d3722ad7
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/d3722ad7

Branch: refs/heads/0.5.0
Commit: d3722ad71cb0baaf3a22e559058d7cedd8109790
Parents: f837ce0
Author: Alex Heneveld <alex.heneveld@cloudsoftcorp.com>
Authored: Sun Mar 3 17:56:46 2013 -0800
Committer: Alex Heneveld <alex.heneveld@cloudsoftcorp.com>
Committed: Tue Mar 5 18:05:31 2013 -0800

----------------------------------------------------------------------
 .../src/main/webapp/assets/css/prettybrook.css  | 105 +++++++++---
 usage/jsgui/src/main/webapp/assets/js/config.js |   4 +-
 .../webapp/assets/js/libs/brooklyn-utils.js     |  26 +++
 .../assets/js/libs/dataTables.extensions.js     |  26 +++
 .../js/libs/dataTables.fnStandingRedraw.js      |  16 --
 .../webapp/assets/js/view/entity-activities.js  |  86 ++++++----
 .../main/webapp/assets/js/view/entity-config.js | 136 +++++++++++----
 .../webapp/assets/js/view/entity-policies.js    |   2 +-
 .../webapp/assets/js/view/entity-sensors.js     | 169 +++++++++++++------
 .../src/main/webapp/assets/js/view/viewutils.js | 112 ++++++++++--
 .../main/webapp/assets/tpl/apps/activities.html |  10 +-
 .../webapp/assets/tpl/apps/activity-row.html    |   5 -
 .../main/webapp/assets/tpl/apps/config-row.html |   6 -
 .../src/main/webapp/assets/tpl/apps/config.html |   8 +-
 .../src/main/webapp/assets/tpl/apps/page.html   |   4 +-
 .../main/webapp/assets/tpl/apps/sensor-row.html |  24 ---
 .../main/webapp/assets/tpl/apps/sensors.html    |   7 +-
 .../main/webapp/assets/tpl/catalog/page.html    |   4 +-
 18 files changed, 529 insertions(+), 221 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/css/prettybrook.css
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/css/prettybrook.css b/usage/jsgui/src/main/webapp/assets/css/prettybrook.css
index f9182f7..d1bc19e 100644
--- a/usage/jsgui/src/main/webapp/assets/css/prettybrook.css
+++ b/usage/jsgui/src/main/webapp/assets/css/prettybrook.css
@@ -35,7 +35,7 @@
 	padding: 15px;
 }
 #application-content .tab-content {
-    max-height: 500px;
+    max-height: 720px;
     overflow: scroll;
 }
 #application-content .template-lozenge {
@@ -426,7 +426,7 @@ input[type="color"]:focus,.uneditable-input:focus {
     height: auto;
 }
 .tab-content {
-	padding: 18px;
+	padding: 12px 18px 18px 18px;
     border-right: 1px solid #DDD;
     border-left: 1px solid #DDD;
     min-height: 300px;
@@ -559,17 +559,62 @@ background-color: #FFFFFF;
 }
 table.dataTable thead th {
 text-align: left;
+background-color: #E0E4E0;
+line-height: 24px;
 }
 table.dataTable {
-margin: 0 auto 4px auto;
-border-width: 0px 0px 1px 0px;
+margin: 0;
+border-width: 2px 0px 2px 0px;
 border-style: solid;
-border-color: gray;
+border-color: black;
+background-color: #fff;
+overflow: scroll;
+/* background-color: #fff;
+ border-top-width: 1px; */
+}
+.bottom {
+	vertical-align: bottom;
+}
+.smallpadside {
+	margin-left: 0.25em;
+	margin-right: 0.25em;
+}
+.table-scroll-wrapper {
+    width: 100%;
+    overflow: scroll;
+    background-color: #ececec;
+	border-style: solid;
+	border-color: #e8e8e8;
+	border-width: 1px 1px 1px 1px;
+	border-bottom-left-radius: 7px;
+	border-bottom-right-radius: 7px;
+}
+.table-scroll-wrapper .dataTables_filter {
+	float: left;
+	padding-left: 6px;
+}
+.table-scroll-wrapper .dataTables_filter label {
+	margin-bottom: 5px;
+	margin-top: 4px;
+}
+.dataTables_wrapper .brook-db-top-toolbar {
+    font-size: 85%;
+    float: right;
+    padding-right: 6px;
+    padding-top: 7px;
+}
+.dataTables_wrapper .brook-db-bot-toolbar {
+    font-size: 85%;
+    float: right;
+    padding-right: 6px;
+    padding-left: 5px;
+    padding-top: 5px;
 }
 
 .dataTables_info {
-	padding-top: 2px;
-	padding-left: 6px;
+	padding-top: 5px;
+	padding-left: 8px;
+	padding-bottom: 8px;
     font-size: 85%;
     width: auto;
     align: center;
@@ -578,11 +623,20 @@ border-color: gray;
 .dataTables_paginate {
     font-size: 85%;
     float: right;
+    margin-top: 6px;
+    margin-bottom: 3px;
+    padding-top: 1px;
+    padding-right: 4px;
+    height: 18px;
+    line-height: 18px;
+}
+.paging_full_numbers a.paginate_active {
+     background-color: #A8B8B0;
 }
 .dataTables_length {
     float: left;
-    padding-left: 0.5em;
-    padding-top: 1px;
+    padding-left: 1em;
+    padding-top: 5px;
 }
 .dataTables_length label {
     font-size: 85%;
@@ -607,25 +661,19 @@ margin: 0;
     background-size:12px 12px;
     background-repeat: no-repeat;
     background-position: 8px 5px;
-    width: 15em;
+    width: 12em;
     font-size: 85%;
     padding: 1px 4px 1px 24px;
-    margin-bottom: 2px;
+    margin-bottom: 1px;
+    border-color: #888C88;
+    /*
     -webkit-border-radius: 1em;
     -moz-border-radius: 1em;
     border-radius: 1em;
-}
-.dataTables_wrapper .brook-db-top-toolbar {
-	font-size: 85%;
-	float: right;
-	padding-right: 6px;
-}
-.dataTables_wrapper .brook-db-bot-toolbar {
-    font-size: 85%;
-    float: left;
-    padding-right: 10px;
-    padding-left: 5px;
-    padding-top: 1px;
+    */
+    -webkit-border-radius: 10px;
+    -moz-border-radius: 10px;
+    border-radius: 10px;
 }
 /* nonDatatables environments want to look a bit like our datatables environment */
 table.nonDatatables {
@@ -642,6 +690,11 @@ table.table.nonDatatables tbody > tr:first-child > td {
 	/* need both bottom of head, and top of body, to support empty table and override non-empty row top border */
 	border-top: 1px black solid;
 }
+table.dataTable tbody tr.selected,
+table.dataTable tr.odd.selected td.sorting_1,
+table.dataTable tr.even.selected td.sorting_1 {
+	background: #AC8 !important;
+},
 table.table.nonDatatables tbody tr.selected,
 table.table.nonDatatables tbody tr.selected td {
     background: #AC8;
@@ -1103,11 +1156,13 @@ textarea {
     width: 15px !important;
     height: 15px !important;
 }
-
-.icon-refresh:hover {
+.green-hover.icon-refresh:hover {
     background: url(../images/application-icon-refresh-hover.png) top left
         !important;
 }
+.table-toolbar-icon:hover {
+	opacity: .7;
+} 
 
 #details {
     background-color: #f0f0f0 !important;

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/js/config.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/config.js b/usage/jsgui/src/main/webapp/assets/js/config.js
index 57f7e70..48e51af 100644
--- a/usage/jsgui/src/main/webapp/assets/js/config.js
+++ b/usage/jsgui/src/main/webapp/assets/js/config.js
@@ -19,7 +19,7 @@ require.config({
         "jquery-ba-bbq":"libs/jquery.ba-bbq.min",
         "handlebars":"libs/handlebars-1.0.rc.1",
         "brooklyn-utils":"libs/brooklyn-utils",
-        "datatables-fnstandingredraw":"libs/dataTables.fnStandingRedraw",
+        "datatables-extensions":"libs/dataTables.extensions",
         "googlemaps":"view/googlemaps",
         "text":"libs/text",
         "tpl":"../tpl"
@@ -35,7 +35,7 @@ require.config({
             deps:[ "underscore", "jquery" ],
             exports:"Backbone"
         },
-        "datatables-fnstandingredraw":{
+        "datatables-extensions":{
             deps:[ "jquery", "jquery-datatables" ]
         }
     }

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js b/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js
index e86f75f..9ce67aa 100644
--- a/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js
+++ b/usage/jsgui/src/main/webapp/assets/js/libs/brooklyn-utils.js
@@ -22,3 +22,29 @@ function setVisibility(obj, visible) {
     if (visible) obj.show()
     else obj.hide()
 }
+
+/** preps data for output */
+function prep(s) {
+    if (s==null) return "";
+    return _.escape(s);
+}
+
+function roundIfNumberToNumDecimalPlaces(v, mantissa) {
+    if (typeof v !== 'number')
+        return v;
+    if (Math.round(v)==v)
+        return v;
+    
+    var vk = v;
+    for (i=0; i<mantissa; i++) {
+        vk *= 10;
+        log(vk)
+        if (Math.round(vk)==vk)
+            return vk;
+    }
+    // rounding needed
+    vk = Math.round(vk);
+    for (i=0; i<mantissa; i++)
+        vk /= 10;
+    return vk;
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/js/libs/dataTables.extensions.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/libs/dataTables.extensions.js b/usage/jsgui/src/main/webapp/assets/js/libs/dataTables.extensions.js
new file mode 100644
index 0000000..62be398
--- /dev/null
+++ b/usage/jsgui/src/main/webapp/assets/js/libs/dataTables.extensions.js
@@ -0,0 +1,26 @@
+/*
+ * jQuery DataTables fnStandingRedraw plug-in.
+ *
+ * http://www.datatables.net/plug-ins/api#fnStandingRedraw
+ */
+$.fn.dataTableExt.oApi.fnStandingRedraw = function(oSettings) {
+    if (oSettings.oFeatures.bServerSide === false) {
+        var before = oSettings._iDisplayStart;
+        oSettings.oApi._fnReDraw(oSettings);
+        // iDisplayStart has been reset to zero - so lets change it back
+        oSettings._iDisplayStart = before;
+        oSettings.oApi._fnCalculateEnd(oSettings);
+    }
+    // draw the 'current' page
+    oSettings.oApi._fnDraw(oSettings);
+};
+
+
+jQuery.fn.dataTableExt.oApi.fnProcessingIndicator = function ( oSettings, onoff )
+{
+    if( typeof(onoff) == 'undefined' )
+    {
+        onoff=true;
+    }
+    this.oApi._fnProcessingDisplay( oSettings, onoff );
+};

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/js/libs/dataTables.fnStandingRedraw.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/libs/dataTables.fnStandingRedraw.js b/usage/jsgui/src/main/webapp/assets/js/libs/dataTables.fnStandingRedraw.js
deleted file mode 100644
index cbd8191..0000000
--- a/usage/jsgui/src/main/webapp/assets/js/libs/dataTables.fnStandingRedraw.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * jQuery DataTables fnStandingRedraw plug-in.
- *
- * http://www.datatables.net/plug-ins/api#fnStandingRedraw
- */
-$.fn.dataTableExt.oApi.fnStandingRedraw = function(oSettings) {
-    if (oSettings.oFeatures.bServerSide === false) {
-        var before = oSettings._iDisplayStart;
-        oSettings.oApi._fnReDraw(oSettings);
-        // iDisplayStart has been reset to zero - so lets change it back
-        oSettings._iDisplayStart = before;
-        oSettings.oApi._fnCalculateEnd(oSettings);
-    }
-    // draw the 'current' page
-    oSettings.oApi._fnDraw(oSettings);
-};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/js/view/entity-activities.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/entity-activities.js b/usage/jsgui/src/main/webapp/assets/js/view/entity-activities.js
index f7389e7..9f6e82d 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/entity-activities.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/entity-activities.js
@@ -2,58 +2,84 @@
  * Displays the list of activities/tasks the entity performed.
  */
 define([
-    "underscore", "backbone", "text!tpl/apps/activities.html", "text!tpl/apps/activity-row.html",
-    "text!tpl/apps/activity-details.html", "bootstrap", "formatJson"
-], function (_, Backbone, ActivitiesHtml, ActivityRowHtml, ActivityDetailsHtml) {
+    "underscore", "jquery", "backbone", "view/viewutils",
+    "text!tpl/apps/activities.html", "text!tpl/apps/activity-details.html", 
+    "bootstrap", "formatJson", "jquery-datatables", "datatables-extensions", "brooklyn-utils"
+], function (_, $, Backbone, ViewUtils, ActivitiesHtml, ActivityDetailsHtml) {
 
     var ActivitiesView = Backbone.View.extend({
         template:_.template(ActivitiesHtml),
-        taskRow:_.template(ActivityRowHtml),
+        table:null,
+        refreshActive:true,
         events:{
-            "click #activities-table tr":"rowClick"
+            "click #activities-table tr":"rowClick",
+            'click .toggleAutoRefresh':'toggleAutoRefresh'
         },
         initialize:function () {
-            var that = this;
-            that.$el.html(that.template({}));
+            this.$el.html(this.template({ }));
+            $.ajaxSetup({ async:false });
+            var that = this,
+                $table = that.$('#activities-table');
             that.collection.url = that.model.getLinkByName("activities");
-            that.collection.fetch();
+            that.table = ViewUtils.myDataTable($table, {
+                "fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
+                    $(nRow).attr('id', aData[0])
+                },
+                "aoColumnDefs": [
+                                 {
+                                     "mRender": function ( data, type, row ) {
+                                         return prep(data)
+                                     },
+                                     "aTargets": [ 0, 1, 2, 3 ]
+                                 },
+                                 { "bVisible": false,  "aTargets": [ 0 ] }
+                             ]            
+            });
+            // TODO domain-specific filters
+            ViewUtils.addAutoRefreshButton(that.table);
+            ViewUtils.addRefreshButton(that.table);
+            
             that.collection.on("reset", that.render, that);
             that.callPeriodically("entity-activities", function () {
-                that.collection.fetch();
-            }, 5000);
+                if (self.refreshActive)
+                    that.collection.fetch();
+            }, 3000);
+            that.collection.fetch();
         },
         beforeClose:function () {
             this.collection.off("reset", this.render);
         },
+        toggleAutoRefresh:function () {
+            ViewUtils.toggleAutoRefresh(this);
+        },
+        enableAutoRefresh: function(isEnabled) {
+            this.refreshActive = isEnabled
+        },
         render:function () {
-            var that = this,
-                $tbody = $("#activities-table tbody").empty();
-            if (this.collection.length==0) {
+            var that = this;
+            if (that.table == null || this.collection.length==0) {
                 $(".has-no-activities").show();
                 $("#activity-details-none-selected").hide();
             } else {
                 $(".has-no-activities").hide();
-                this.collection.each(function (task) {
-                    $tbody.append(that.taskRow({
-                        cid:task.get("id"),
-                        displayName:task.get("displayName"),
-                        submitTimeUtc:task.get("submitTimeUtc"),
-                        startTimeUtc:task.get("startTimeUtc"),
-                        endTimeUtc:task.get("endTimeUtc"),
-                        currentStatus:task.get("currentStatus"),
-                        entityDisplayName:task.get("entityDisplayName")
-                    }));
-                if (that.activeTask) {
-                    $("#activities-table tr[id='"+that.activeTask+"']").addClass("selected");
-                    that.showFullActivity(that.activeTask);
-                } else {
-                    $("#activity-details-none-selected").show();
-                }
-            });
+                ViewUtils.updateMyDataTable(that.table, that.collection, function(task, index) {
+                    return [ 
+                                  // columns are: id, name, when submitted, status         
+                                  task.get("id"),
+                                  task.get("displayName"),
+                                  task.get("submitTimeUtc"),
+                                  task.get("currentStatus")
+                              ];
+                    //also have:
+//                  startTimeUtc:task.get("startTimeUtc"),
+//                  endTimeUtc:task.get("endTimeUtc"),
+//                  entityDisplayName:task.get("entityDisplayName")
+                })
             }
             return this;
         },
         rowClick:function(evt) {
+            // TODO link row click, and details stuff
             var row = $(evt.currentTarget).closest("tr");
             var id = row.attr("id");
             $("#activities-table tr").removeClass("selected");

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/js/view/entity-config.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/entity-config.js b/usage/jsgui/src/main/webapp/assets/js/view/entity-config.js
index 394ef6a..7679bc5 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/entity-config.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/entity-config.js
@@ -5,39 +5,76 @@
  */
 define([
     "underscore", "jquery", "backbone",
-    "view/viewutils", "model/config-summary", "text!tpl/apps/config.html", "text!tpl/apps/config-row.html",
-    "jquery-datatables", "datatables-fnstandingredraw"
-], function (_, $, Backbone, ViewUtils, ConfigSummary, ConfigHtml, ConfigRowHtml) {
+    "view/viewutils", "model/config-summary", "text!tpl/apps/config.html",
+    "jquery-datatables", "datatables-extensions", "brooklyn-utils"
+], function (_, $, Backbone, ViewUtils, ConfigSummary, ConfigHtml) {
 
     var EntityConfigView = Backbone.View.extend({
         template:_.template(ConfigHtml),
-        configTemplate:_.template(ConfigRowHtml),
+        configMetadata:{},
+        refreshActive:true,
         events:{
             'click .refresh':'refreshConfig',
-            'click .filterEmpty':'toggleFilterEmpty'
+            'click .filterEmpty':'toggleFilterEmpty',
+            'click .toggleAutoRefresh':'toggleAutoRefresh'
         },
         initialize:function () {
         	this.$el.html(this.template({ }));
             $.ajaxSetup({ async:false });
             var that = this,
-                configCollection = new ConfigSummary.Collection,
-                $table = this.$('#config-table'),
-                $tbody = this.$('tbody').empty();
-            configCollection.url = that.model.getLinkByName('config');
-            configCollection.fetch({ success:function () {
-                configCollection.each(function (config) {
-                    $tbody.append(that.configTemplate({
-                        name:config.get("name"),
-                        description:config.get("description"),
-                        value:'', // will be set later
-                        type:config.get("type")
-                    }));
-                });
-                $tbody.find('*[rel="tooltip"]').tooltip();
-                that.updateConfigPeriodically(that);
-                ViewUtils.myDataTable($table);
-                $table.dataTable().fnAdjustColumnSizing();
-            }});
+                $table = this.$('#config-table');
+            that.table = ViewUtils.myDataTable($table, {
+                "fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
+                    $(nRow).attr('id', aData[0])
+                    $('td',nRow).each(function(i,v){
+                        if (i==1) $(v).attr('class','config-actions');
+                        if (i==2) $(v).attr('class','config-value');
+                    })
+                    return nRow;
+                },
+                "aoColumnDefs": [
+                                 { // name, with tooltip
+                                     "mRender": function ( data, type, row ) {
+                                         // name (column 1) should have tooltip title
+                                         return '<span class="config-name" '+ 
+                                             'rel="tooltip" title="<b>'+
+                                             prep(data['description'])+'</b><br/>('+
+                                             prep(data['type'])+')" data-placement="left">'+
+                                             prep(data['name'])+'</span>';
+                                     },
+                                     "aTargets": [ 1 ]
+                                 },
+                                 { // actions (just one, json link hard coded here apart from url)
+                                     "mRender": function ( link, type, row ) {
+                                         if (link=="") return "";
+                                         var text=""
+                                         var icon="icon-file"
+                                         var title="JSON direct link"
+                                         var actionsText = 
+                                             "<a href='"+prep(link)+"'"+
+                                             " class='"+prep(icon)+"'"+
+                                             " title='"+prep(title)+"'>"+
+                                             prep(text)+"</a>\n";
+                                         //just one action here
+                                         return actionsText;
+                                     },
+                                     "aTargets": [ 2 ]
+                                 },
+                                 { // value
+                                     "mRender": function ( data, type, row ) {
+                                         return prep(roundIfNumberToNumDecimalPlaces(data, 4))
+                                     },
+                                     "aTargets": [ 3 ]
+                                 },
+                                 // ID in column 0 is standard (assumed in ViewUtils)
+                                 { "bVisible": false,  "aTargets": [ 0 ] /* hide id column */ },
+                             ]            
+            });
+            ViewUtils.addFilterEmptyButton(that.table);
+            ViewUtils.addAutoRefreshButton(that.table);
+            ViewUtils.addRefreshButton(that.table);
+            that.loadConfigMetadata(that);
+            that.updateConfigPeriodically(that);
             that.toggleFilterEmpty();
         },
         render:function () {
@@ -45,34 +82,59 @@ define([
             return this;
         },
         toggleFilterEmpty:function () {
-            ViewUtils.toggleFilterEmpty(this.$('#config-table'), 1);
+            ViewUtils.toggleFilterEmpty(this.$('#config-table'), 3);
+        },
+        toggleAutoRefresh:function () {
+            ViewUtils.toggleAutoRefresh(this);
+        },
+        enableAutoRefresh: function(isEnabled) {
+            this.refreshActive = isEnabled
         },
         refreshConfig:function () {
             this.updateConfigNow(this);  
         },
-        // register a callback to update the sensors
         updateConfigPeriodically:function (that) {
             var self = this;
-            that.updateConfigNow(that);
             that.callPeriodically("entity-config", function() {
-                self.updateConfigNow(that);
+                if (self.refreshActive)
+                    self.updateConfigNow(that);
             }, 3000);
         },
+        loadConfigMetadata: function(that) {
+            var url =  that.model.getLinkByName('config');
+            $.get(url, function (data) {
+                for (d in data) {
+                    var config = data[d];
+                    that.configMetadata[config["name"]] = {
+                          name:config["name"],
+                          description:config["description"],
+                          actionGetData:config["links"]["self"],
+                          type:config["type"]
+                    }
+                }
+                that.updateConfigNow(that);
+                that.table.find('*[rel="tooltip"]').tooltip();
+            });
+        },
         updateConfigNow:function (that) {
-            // NB: this won't add new dynamic config
             var url = that.model.getConfigUpdateUrl(),
-                $table = that.$('#config-table'),
-                $rows = that.$("tr.config-row");
+                $table = that.$('#config-table');
             $.get(url, function (data) {
-                // iterate over the config table and update each value
-                $rows.each(function (index, row) {
-                    var key = $(this).find(".config-name").text();
-                    var v = data[key];
-                    if (v === undefined) v = '';
-                    $table.dataTable().fnUpdate(_.escape(v), row, 1, false);
+                ViewUtils.updateMyDataTable($table, data, function(value, name) {
+                    var metadata = that.configMetadata[name]
+                    if (metadata==null) {                        
+                        // TODO should reload metadata when this happens (new sensor for which no metadata known)
+                        // (currently if we have dynamic sensors, their metadata won't appear
+                        // until the page is refreshed; don't think that's a bit problem -- mainly tooltips
+                        // for now, we just return the partial value
+                        return [name, {'name':name}, "", value]
+                    } 
+                    return [name, metadata,
+                        metadata["actionGetData"],
+                        value
+                    ];
                 });
             });
-            $table.dataTable().fnStandingRedraw();
         }
     });
     return EntityConfigView;

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/js/view/entity-policies.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/entity-policies.js b/usage/jsgui/src/main/webapp/assets/js/view/entity-policies.js
index e126b6b..1913759 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/entity-policies.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/entity-policies.js
@@ -7,7 +7,7 @@
 define([
     "underscore", "jquery", "backbone",
     "model/policy-summary", "model/policy-config-summary", "view/viewutils", "view/policy-config-invoke", "text!tpl/apps/policy.html", "text!tpl/apps/policy-row.html", "text!tpl/apps/policy-config-row.html",
-    "jquery-datatables", "datatables-fnstandingredraw"
+    "jquery-datatables", "datatables-extensions"
 ], function (_, $, Backbone, PolicySummary, PolicyConfigSummary, ViewUtils, PolicyConfigInvokeView, PolicyHtml, PolicyRowHtml, PolicyConfigRowHtml) {
 
     var EntityPoliciesView = Backbone.View.extend({

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/js/view/entity-sensors.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/entity-sensors.js b/usage/jsgui/src/main/webapp/assets/js/view/entity-sensors.js
index 50b3748..398cbe0 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/entity-sensors.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/entity-sensors.js
@@ -5,46 +5,86 @@
  */
 define([
     "underscore", "jquery", "backbone",
-    "view/viewutils", "model/sensor-summary", "text!tpl/apps/sensors.html", "text!tpl/apps/sensor-row.html",
-    "jquery-datatables", "datatables-fnstandingredraw"
-], function (_, $, Backbone, ViewUtils, SensorSummary, SensorsHtml, SensorRowHtml) {
+    "view/viewutils", "model/sensor-summary", "text!tpl/apps/sensors.html", 
+    "jquery-datatables", "datatables-extensions", "brooklyn-utils"
+], function (_, $, Backbone, ViewUtils, SensorSummary, SensorsHtml) {
 
     var EntitySensorsView = Backbone.View.extend({
         template:_.template(SensorsHtml),
-        sensorTemplate:_.template(SensorRowHtml),
+        sensorMetadata:{},
+        refreshActive:true,
         events:{
             'click .refresh':'refreshSensors',
-            'click .filterEmpty':'toggleFilterEmpty'
+            'click .filterEmpty':'toggleFilterEmpty',
+            'click .toggleAutoRefresh':'toggleAutoRefresh'
         },
         initialize:function () {
             this.$el.html(this.template({ }));
             $.ajaxSetup({ async:false });
             var that = this,
-                sensorsCollection = new SensorSummary.Collection,
-                $table = this.$('#sensors-table'),
-                $tbody = this.$('tbody').empty();
-            sensorsCollection.url = that.model.getLinkByName('sensors');
-            sensorsCollection.fetch({ success:function () {
-                sensorsCollection.each(function (sensor) {
-                    var actions = {};
-                    _.each(sensor.get("links"), function(v,k) {
-                        if (k.slice(0, 7) == "action:") {
-                            actions[k.slice(7)] = v;
-                        }
-                    });
-                    $tbody.append(that.sensorTemplate({
-                        name:sensor.get("name"),
-                        description:sensor.get("description"),
-                        actions:actions,
-                        type:sensor.get("type"),
-                        value:'' // will be set later
-                    }));
-                });
-                $tbody.find('*[rel="tooltip"]').tooltip();
-                that.updateSensorsPeriodically(that);
-                ViewUtils.myDataTable($table);
-                $table.dataTable().fnAdjustColumnSizing();
-            }});
+                $table = this.$('#sensors-table');
+            that.table = ViewUtils.myDataTable($table, {
+                "fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
+                    $(nRow).attr('id', aData[0])
+                    $('td',nRow).each(function(i,v){
+                        if (i==1) $(v).attr('class','sensor-actions');
+                        if (i==2) $(v).attr('class','sensor-value');
+                    })
+                    return nRow;
+                },
+                "aoColumnDefs": [
+                                 { // name (with tooltip)
+                                     "mRender": function ( data, type, row ) {
+                                         // name (column 1) should have tooltip title
+                                         return '<span class="sensor-name" '+ 
+                                             'rel="tooltip" title="<b>'+
+                                             prep(data['description'])+'</b><br/>('+
+                                             prep(data['type'])+')" data-placement="left">'+
+                                             prep(data['name'])+'</span>';
+                                     },
+                                     "aTargets": [ 1 ]
+                                 },
+                                 { // actions
+                                     "mRender": function ( actions, type, row ) {
+                                         var actionsText = ""
+                                         _.each(actions, function(v,k) {
+                                             var text=k
+                                             var icon=""
+                                             var title=""
+                                             if (k=="json") {
+                                                 icon="icon-file"
+                                                 title="JSON direct link"
+                                             }
+                                             if (k=="open") {
+                                                 icon="icon-home"
+                                                 title="Open URL"
+                                             }
+                                             if (icon!="") text=""
+                                             actionsText = actionsText +
+                                                 "<a href='"+prep(v)+"'"+
+                                         		" class='"+prep(icon)+"'"+
+                                         		" title='"+prep(title)+"'>"+
+                                         		prep(text)+"</a>\n";
+                                         })
+                                         return actionsText;
+                                     },
+                                     "aTargets": [ 2 ]
+                                 },
+                                 { // value
+                                     "mRender": function ( data, type, row ) {
+                                         return prep(roundIfNumberToNumDecimalPlaces(data, 4))
+                                     },
+                                     "aTargets": [ 3 ]
+                                 },
+                                 // ID in column 0 is standard (assumed in ViewUtils)
+                                 { "bVisible": false,  "aTargets": [ 0 ] },
+                             ]            
+            });
+            ViewUtils.addFilterEmptyButton(that.table);
+            ViewUtils.addAutoRefreshButton(that.table);
+            ViewUtils.addRefreshButton(that.table);
+            that.loadSensorMetadata(that);
+            that.updateSensorsPeriodically(that);
             that.toggleFilterEmpty();
         },
         render:function () {
@@ -52,44 +92,65 @@ define([
             return this;
         },
         toggleFilterEmpty:function () {
-            ViewUtils.toggleFilterEmpty(this.$('#sensors-table'), 2);
+            ViewUtils.toggleFilterEmpty(this.$('#sensors-table'), 3);
+        },
+        toggleAutoRefresh:function () {
+            ViewUtils.toggleAutoRefresh(this);
+        },
+        enableAutoRefresh: function(isEnabled) {
+            this.refreshActive = isEnabled
         },
         refreshSensors:function () {
             this.updateSensorsNow(this);  
         },
-        // register a callback to update the sensors
         updateSensorsPeriodically:function (that) {
             var self = this;
-            that.updateSensorsNow(that);
             that.callPeriodically("entity-sensors", function() {
-                self.updateSensorsNow(that);
+                if (self.refreshActive)
+                    self.updateSensorsNow(that);
             }, 3000);
         },
-        updateSensorsNow:function (that) {
-            // NB: this won't add new dynamic sensors
-            var url = that.model.getSensorUpdateUrl(),
-                $table = that.$('#sensors-table'),
-                $rows = that.$("tr.sensor-row");
+        loadSensorMetadata: function(that) {
+            var url =  that.model.getLinkByName('sensors');
             $.get(url, function (data) {
-                // iterate over the sensors table and update each sensor
-                $rows.each(function (index, row) {
-                    var key = $(this).find(".sensor-name").text();
-                    var v = data[key];
-                    if (v === undefined || v === null) v = '';
-                    else if (typeof v === 'number') {
-                        if (Math.round(v)!=v) {
-                            // not an integer, check if it needs rounding
-                            var vk = v*1000; 
-                            if (Math.round(vk)!=vk) {
-                                // needs rounding
-                                v = Math.round(vk)/1000;
-                            }
+                for (d in data) {
+                    var sensor = data[d];
+                    var actions = {};
+                    _.each(sensor["links"], function(v,k) {
+                        if (k.slice(0, 7) == "action:") {
+                            actions[k.slice(7)] = v;
                         }
+                    });
+                    that.sensorMetadata[sensor["name"]] = {
+                          name:sensor["name"],
+                          description:sensor["description"],
+                          actions:actions,
+                          type:sensor["type"]
                     }
-                    $table.dataTable().fnUpdate(_.escape(v), row, 2, false);
+                }
+                that.updateSensorsNow(that);
+                that.table.find('*[rel="tooltip"]').tooltip();
+            });
+        },
+        updateSensorsNow:function (that) {
+            var url = that.model.getSensorUpdateUrl(),
+                $table = that.$('#sensors-table');
+            $.get(url, function (data) {
+                ViewUtils.updateMyDataTable($table, data, function(value, name) {
+                    var metadata = that.sensorMetadata[name]
+                    if (metadata==null) {                        
+                        // TODO should reload metadata when this happens (new sensor for which no metadata known)
+                        // (currently if we have dynamic sensors, their metadata won't appear
+                        // until the page is refreshed; don't think that's a bit problem -- mainly tooltips
+                        // for now, we just return the partial value
+                        return [name, {'name':name}, {}, value]
+                    } 
+                    return [name, metadata,
+                        metadata["actions"],
+                        value
+                    ];
                 });
             });
-            $table.dataTable().fnStandingRedraw();
         }
     });
     return EntitySensorsView;

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/js/view/viewutils.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/view/viewutils.js b/usage/jsgui/src/main/webapp/assets/js/view/viewutils.js
index 8b879f7..e4a16d0 100644
--- a/usage/jsgui/src/main/webapp/assets/js/view/viewutils.js
+++ b/usage/jsgui/src/main/webapp/assets/js/view/viewutils.js
@@ -3,15 +3,15 @@ define([
 ], function (_, $, Backbone) {
 
     var ViewUtils = {
-        myDataTable:function($table) {
-            $table.dataTable({
+        myDataTable:function($table, extra) {
+            var settings = {
                 "bDestroy": true,
                 "iDisplayLength": 25,
                 "sPaginationType": "full_numbers",
-                "sDom": "f<'brook-db-top-toolbar'>t<'brook-db-bot-toolbar'>ilp",
+                "sDom": "fp<'brook-db-top-toolbar'>tilp<'brook-db-bot-toolbar'>",
                 "oLanguage": {
                     "sSearch": "",
-                    "sInfo": "_START_ - _END_ of _TOTAL_ ",
+                    "sInfo": "Showing _START_ - _END_ of _TOTAL_ ",
                     "sInfoEmpty": "<i>No data</i> ",
                     "sEmptyTable": "<i>No matching records available</i>",
                     "sZeroRecords": "<i>No matching records found</i>",
@@ -23,17 +23,94 @@ define([
                     },
                     "sInfoFiltered": "(of _MAX_)",
                     "sLengthMenu": '( <select>' +
+                                        '<option value="10">10</option>' +
                                         '<option value="25">25</option>' +
                                         '<option value="50">50</option>' +
                                         '<option value="-1">all</option>' +
                                     '</select> / page )'
                 }
-            });
-            $('.brook-db-bot-toolbar', $table.parent().parent()).html(
-                    '<i class="refresh icon-refresh handy" rel="tooltip" title="Reload immediately."></i>' +
-                    '&nbsp;&nbsp;' +
-                    '<i class="filterEmpty icon-eye-open handy" rel="tooltip" title="Show/hide empty records"></i>'
-            );
+            };
+            for (prop in extra) { 
+                settings[prop] = extra[prop];
+            }
+            var result = $table.dataTable(settings);
+            return result;
+        },
+        myDataTableToolbarAddHtml: function($table,html) {
+            $('.brook-db-bot-toolbar', $table.parent().parent()).append(html)
+            $('.brook-db-top-toolbar', $table.parent().parent()).append(html)
+        },
+        addRefreshButton: function($table) {
+            this.myDataTableToolbarAddHtml($table,
+            '<i class="refresh table-toolbar-icon icon-refresh handy smallpadside" rel="tooltip" title="Reload content immediately"></i>');
+        },
+        addFilterEmptyButton: function($table) {
+            this.myDataTableToolbarAddHtml($table,
+                '<i class="filterEmpty table-toolbar-icon icon-eye-open handy bottom smallpadside" rel="tooltip" title="Show/hide empty records"></i>');
+        },
+        addAutoRefreshButton: function($table) {
+            this.myDataTableToolbarAddHtml($table,
+                '<i class="toggleAutoRefresh table-toolbar-icon icon-pause handy smallpadside" rel="tooltip" title="Toggle auto-refresh"></i>');
+        },
+        /* fnConvertData takes the entries in collection (value, optionalKeyOrIndex) and returns a list
+         * whose first element is the ID (hidden first column of table)
+         * and other elements are the other columns in the table;
+         * alternatively it can return null if the entry should be excluded
+         */ 
+        updateMyDataTable: function(table, collection, fnConvertData) {
+            if (table==null) return;
+            var oldDisplayDataList = table.dataTable().fnGetData();
+            var oldDisplayIndexMap = {}
+            var oldDisplayData = {}
+            for (idx in oldDisplayDataList) {
+                var data = oldDisplayDataList[idx]
+                oldDisplayIndexMap[data[0]] = idx
+                oldDisplayData[data[0]] = data
+            }
+            newDisplayData = {}
+            updateDisplayData = []
+            ViewUtils.each(collection, function(data,index) { 
+                var newRow = fnConvertData(data, index)
+                if (newRow!=null) {
+                    var id = newRow[0]
+
+                    var displayIndex = oldDisplayIndexMap[id];
+                    if (displayIndex!=null) {
+                        updateDisplayData[displayIndex] = newRow
+                        delete oldDisplayIndexMap[id]
+                    } else {
+                        newDisplayData[id] = newRow
+                    }
+                }
+            })
+            // first update (so indices don't change)
+            for (prop in updateDisplayData) {
+                var rowProps = updateDisplayData[prop]
+                var oldProps = oldDisplayData[rowProps[0]]
+                for (idx in rowProps) {
+                    var v = rowProps[idx]
+                    if (!_.isEqual(v,oldProps[idx])) {
+                        // update individual columns as values change
+//                        log("updating "+v+" in "+prop+"["+idx+"]")
+                        table.fnUpdate( v, Number(prop), idx, false, false )
+                    } else {
+//                        log("NO CHANGE")
+                    }
+                }
+            }
+            // then delete old ones
+            for (prop in oldDisplayIndexMap) {
+                var index = oldDisplayIndexMap[prop]
+//                log("deleting "+index)
+                table.fnDeleteRow( Number(index), null, false )
+            }
+            // and now add new ones
+            for (prop in newDisplayData) {
+//                log("adding "+newDisplayData[prop])
+                table.fnAddData( newDisplayData[prop] )
+            }
+            table.fnAdjustColumnSizing();
+            table.fnStandingRedraw();
         },
         toggleFilterEmpty: function($table, column) {
             var hideEmpties = $('.filterEmpty', $table.parent().parent()).toggleClass('icon-eye-open icon-eye-close').hasClass('icon-eye-close');
@@ -43,7 +120,10 @@ define([
                 $table.dataTable().fnFilter('.*', column, true);
             }
         },
-
+        toggleAutoRefresh: function(pane) {
+            var isEnabled = $('.toggleAutoRefresh', pane.$el).toggleClass('icon-pause icon-play').hasClass('icon-pause');
+            pane.enableAutoRefresh(isEnabled);
+        },
         attachToggler: function($scope) {
             var $togglers;
             if ($scope === undefined) {
@@ -84,6 +164,16 @@ define([
             } else {
                 $div.hide();
             }
+        },
+        each: function(collection, fn) {
+            if (typeof collection.each == 'function') {
+                // some objects (such as backbone collections) are not iterable
+                // (either by "for x in" or "_.each") so call the "each" method explicitly on them 
+                return collection.each(fn)
+            } else {
+                // try underscore
+                return _.each(collection, fn);
+            }
         }
     };
     return ViewUtils;

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/tpl/apps/activities.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/apps/activities.html b/usage/jsgui/src/main/webapp/assets/tpl/apps/activities.html
index a854421..9839826 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/apps/activities.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/apps/activities.html
@@ -1,6 +1,8 @@
-<table id="activities-table" class="table table-striped table-condensed nonDatatables" style="width: 100%;">
+<div class="table-scroll-wrapper">
+<table id="activities-table" width="100%">
     <thead>
     <tr>
+        <th width="10%">ID</th>
         <th width="40%">Task</th>
         <th width="30%">Submitted</th>
         <th width="30%">Status</th>
@@ -8,6 +10,10 @@
     </thead>
     <tbody></tbody>
 </table>
+</div>
+
+<div>&nbsp;</div>
+
 <div class="has-no-activities for-empty-table hide">
     <i>No activities currently available on this entity</i>
 </div>
@@ -16,5 +22,5 @@
 </div>
 
 <div id="activity-details-none-selected">
-    <i>Select an entity above to view details.</i>
+    <i>Select an entry above to view details.</i>
 </div>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/tpl/apps/activity-row.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/apps/activity-row.html b/usage/jsgui/src/main/webapp/assets/tpl/apps/activity-row.html
deleted file mode 100644
index 7f1dca7..0000000
--- a/usage/jsgui/src/main/webapp/assets/tpl/apps/activity-row.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<tr class="activity-row" id="<%= cid %>">
-    <td class="task-display-name"><%= displayName %></td>
-    <td class="submit-time"><%= submitTimeUtc %></td>
-    <td class="current-status"><%= currentStatus %></td>
-</tr>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/tpl/apps/config-row.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/apps/config-row.html b/usage/jsgui/src/main/webapp/assets/tpl/apps/config-row.html
deleted file mode 100644
index 8ee0624..0000000
--- a/usage/jsgui/src/main/webapp/assets/tpl/apps/config-row.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<tr class="config-row">
-    <td><span class="config-name" 
-        rel="tooltip" title="<b><%= description %></b><br/>(<%= type %>)" data-placement="left"
-        ><%= name %></span></td>
-    <td class="config-value"><%= (value === undefined ? "" : value) %></td>
-</tr>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/tpl/apps/config.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/apps/config.html b/usage/jsgui/src/main/webapp/assets/tpl/apps/config.html
index 7c47018..ab37a27 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/apps/config.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/apps/config.html
@@ -1,9 +1,13 @@
-<table id="config-table" style="width: 554px;">
+<div class="table-scroll-wrapper">
+<table id="config-table" width="100%">
     <thead>
     <tr>
+        <th>ID</th>
         <th>Name</th>
+        <th>Actions</th>
         <th>Value</th>
     </tr>
     </thead>
     <tbody></tbody>
-</table>
\ No newline at end of file
+</table>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/tpl/apps/page.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/apps/page.html b/usage/jsgui/src/main/webapp/assets/tpl/apps/page.html
index 4a20a87..a5314dd 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/apps/page.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/apps/page.html
@@ -3,9 +3,9 @@
 		<div class="navbar_top">
 			<h3>Applications</h3>
 			<div class="apps-tree-toolbar">
-				<i id="add-new-application" class="icon-plus-sign handy" />
+				<i id="add-new-application" class="icon-plus-sign handy green-hover" />
 				&nbsp;
-				<i class="icon-refresh refresh handy" />
+				<i class="icon-refresh refresh handy green-hover" />
 			</div>
 		</div>
 		<div class="navbar_main_wrapper cssninja">

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/tpl/apps/sensor-row.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/apps/sensor-row.html b/usage/jsgui/src/main/webapp/assets/tpl/apps/sensor-row.html
deleted file mode 100644
index eaac4b7..0000000
--- a/usage/jsgui/src/main/webapp/assets/tpl/apps/sensor-row.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<tr class="sensor-row">
-    <td><span class="sensor-name" 
-        rel="tooltip" title="<b><%= description %></b><br/>(<%= type %>)" data-placement="left"
-        ><%= name %></span></td>
-    <td class="sensor-actions">
-        <% _.each(actions, function(v,k) {
-            var text=k
-            var icon=""
-            var title=""
-            if (k=="json") {
-                icon="icon-file"
-                title="JSON direct link"
-            }
-            if (k=="open") {
-                icon="icon-home"
-                title="Open URL"
-            }
-            if (icon!="") text=""
-        %>
-            <a href="<%= v %>" class="<%= icon %>" title="<%= title %>"><%= text %></a>
-        <% }) %>
-    </td>
-    <td class="sensor-value"><%= value %></td>
-</tr>

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/tpl/apps/sensors.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/apps/sensors.html b/usage/jsgui/src/main/webapp/assets/tpl/apps/sensors.html
index 845adb4..819c269 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/apps/sensors.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/apps/sensors.html
@@ -1,10 +1,13 @@
-<table id="sensors-table" style="width: 554px;">
+<div class="table-scroll-wrapper">
+<table id="sensors-table" width="100%">
     <thead>
     <tr>
+        <th>ID</th>
         <th>Name</th>
         <th>Actions</th>
         <th>Value</th>
     </tr>
     </thead>
     <tbody></tbody>
-</table>
\ No newline at end of file
+</table>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/d3722ad7/usage/jsgui/src/main/webapp/assets/tpl/catalog/page.html
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/tpl/catalog/page.html b/usage/jsgui/src/main/webapp/assets/tpl/catalog/page.html
index 18497b7..b0ef309 100644
--- a/usage/jsgui/src/main/webapp/assets/tpl/catalog/page.html
+++ b/usage/jsgui/src/main/webapp/assets/tpl/catalog/page.html
@@ -5,9 +5,9 @@
         <div class="navbar_top">
             <h3>Catalog</h3>
             <div class="apps-tree-toolbar">
-                <i id="add-new-thing" class="icon-plus-sign handy" />
+                <i id="add-new-thing" class="icon-plus-sign handy green-hover" />
                 &nbsp;
-                <i class="icon-refresh refresh handy" />
+                <i class="icon-refresh refresh handy green-hover" />
             </div>
         </div>
         <div class="navbar_main_wrapper cssninja">


Mime
View raw message