From 5af9b4c54279d2dd39bb2c0613eb79b6ec07b5c9 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Mon, 7 Apr 2014 14:10:08 -0400
Subject: [PATCH] Refactored UI framework.

Previously the content of table cells was generated by JavaScript
code. Now the content can be defined in the HTML template to allow
cleaner separation from the code. Attributes of the entry being
displayed in the row can now be specified in the template using
${attribute} notation. A special attribute called "parent" can be
used to refer to the attributes of the parent object. The current
templates have been modified to utilize this feature.

The renderIDColumn() in TableItem is no longer needed so it has been
removed. An open() method is added to handle any links in the cell.
The PropertiesTableItem has been moved into tps.js.

The "attributes" property in Dialog and EntryPage has been renamed
to "entry".

Ticket #654
---
 base/server/share/webapps/pki/js/pki-ui.js         | 105 ++++++++++++---------
 base/tps-tomcat/shared/webapps/tps/js/audit.js     |  10 +-
 base/tps-tomcat/shared/webapps/tps/js/config.js    |  19 ----
 base/tps-tomcat/shared/webapps/tps/js/tps.js       |  45 +++++++--
 base/tps-tomcat/shared/webapps/tps/js/user.js      |   8 +-
 .../shared/webapps/tps/ui/activities.html          |  14 +--
 base/tps-tomcat/shared/webapps/tps/ui/audit.html   |   4 +-
 .../shared/webapps/tps/ui/authenticator.html       |   4 +-
 .../shared/webapps/tps/ui/authenticators.html      |   4 +-
 base/tps-tomcat/shared/webapps/tps/ui/certs.html   |  18 ++--
 base/tps-tomcat/shared/webapps/tps/ui/config.html  |   4 +-
 .../shared/webapps/tps/ui/connection.html          |   4 +-
 .../shared/webapps/tps/ui/connections.html         |   4 +-
 base/tps-tomcat/shared/webapps/tps/ui/groups.html  |   4 +-
 .../shared/webapps/tps/ui/profile-mapping.html     |   4 +-
 .../shared/webapps/tps/ui/profile-mappings.html    |   4 +-
 base/tps-tomcat/shared/webapps/tps/ui/profile.html |   4 +-
 .../tps-tomcat/shared/webapps/tps/ui/profiles.html |   4 +-
 .../shared/webapps/tps/ui/selftests.html           |  10 +-
 base/tps-tomcat/shared/webapps/tps/ui/tokens.html  |  16 ++--
 base/tps-tomcat/shared/webapps/tps/ui/users.html   |   4 +-
 21 files changed, 160 insertions(+), 133 deletions(-)

diff --git a/base/server/share/webapps/pki/js/pki-ui.js b/base/server/share/webapps/pki/js/pki-ui.js
index 5f4251bbef0b54b2dc4f7b515056b5f536b27040..58c860974e9a8df3441e973f810135f2559fbe2c 100644
--- a/base/server/share/webapps/pki/js/pki-ui.js
+++ b/base/server/share/webapps/pki/js/pki-ui.js
@@ -299,7 +299,7 @@ var Dialog = Backbone.View.extend({
     loadField: function(input) {
         var self = this;
         var name = input.attr("name");
-        var value = self.attributes[name];
+        var value = self.entry[name];
         if (value === undefined) value = "";
         input.val(value);
     },
@@ -315,7 +315,7 @@ var Dialog = Backbone.View.extend({
         var self = this;
         var name = input.attr("name");
         var value = input.val();
-        self.attributes[name] = value;
+        self.entry[name] = value;
     }
 });
 
@@ -351,9 +351,11 @@ var TableItem = Backbone.View.extend({
         var self = this;
         var prefix = self.table.$el.attr("name") + "_select_";
 
+        var templateTDs = $("td", self.table.template);
         $("td", self.$el).each(function(index) {
             var td = $(this);
             var name = td.attr("name");
+            var templateTD = $(templateTDs[index]);
 
             if (td.hasClass("pki-select-column")) {
                 // generate a unique input ID based on entry ID
@@ -371,11 +373,8 @@ var TableItem = Backbone.View.extend({
                 label.attr("for", inputID);
                 label.show();
 
-            } else if (name == "id") {
-                self.renderIDColumn(td);
-
             } else {
-                self.renderColumn(td);
+                self.renderColumn(td, templateTD);
             }
         });
     },
@@ -384,26 +383,45 @@ var TableItem = Backbone.View.extend({
         var attribute = self.table.columnMappings[name] || name;
         return self.entry[attribute];
     },
-    renderIDColumn: function(td) {
+    renderColumn: function(td, templateTD) {
         var self = this;
 
-        // show content as link to open item
-        td.empty();
-        $("<a/>", {
-            href: "#",
-            text: self.get("id"),
-            click: function(e) {
-                self.table.open(self);
-                e.preventDefault();
+        // copy content from template
+        var content = templateTD.html();
+        var newContent = "";
+
+        // substitute ${attribute} with attribute value
+        var pattern = /\${([^}]*)}/;
+
+        while (content.length) {
+            // search for ${attribute} pattern
+            var index = content.search(pattern);
+            if (index < 0) {
+                newContent += content;
+                break;
             }
-        }).appendTo(td);
+
+            var name = RegExp.$1;
+            var value = self.get(name);
+
+            // replace pattern occurance with attribute value
+            newContent += content.substring(0, index) + (value === undefined ? "" : value);
+
+            // process the remaining content
+            content = content.substring(index + name.length + 3);
+        }
+
+        td.html(newContent);
+
+        // add link handler
+        $("a", td).click(function(e) {
+            self.open(td);
+            e.preventDefault();
+        });
     },
-    renderColumn: function(td) {
+    open: function(td) {
         var self = this;
-
-        // show content in plain text
-        var name = td.attr("name");
-        td.text(self.get(name));
+        self.table.open(self);
     }
 });
 
@@ -415,6 +433,7 @@ var Table = Backbone.View.extend({
         self.entries = options.entries || [];
         self.columnMappings = options.columnMappings || {};
         self.mode = options.mode || "view";
+        self.parent = options.parent;
 
         self.addDialog = options.addDialog;
         self.editDialog = options.editDialog;
@@ -620,7 +639,7 @@ var Table = Backbone.View.extend({
 
                 // save changes
                 dialog.save();
-                _.extend(item.entry, dialog.attributes);
+                _.extend(item.entry, dialog.entry);
 
                 // redraw table
                 self.render();
@@ -628,7 +647,7 @@ var Table = Backbone.View.extend({
             });
         }
 
-        dialog.attributes = _.clone(item.entry);
+        dialog.entry = _.clone(item.entry);
 
         dialog.open();
     },
@@ -636,13 +655,13 @@ var Table = Backbone.View.extend({
         var self = this;
 
         var dialog = self.addDialog;
-        dialog.attributes = {};
+        dialog.entry = {};
 
         dialog.handler("add", function() {
 
             // save new entry
             dialog.save();
-            self.entries.push(dialog.attributes);
+            self.entries.push(dialog.entry);
 
             // redraw table
             self.render();
@@ -722,13 +741,13 @@ var ModelTable = Table.extend({
         var model = self.collection.get(item.entry.id);
 
         var dialog = self.editDialog;
-        dialog.attributes = item.entry;
+        dialog.entry = item.entry;
 
         dialog.handler("save", function() {
 
             // save attribute changes
             dialog.save();
-            model.set(dialog.attributes);
+            model.set(dialog.entry);
 
             // if nothing has changed, return
             var changedAttributes = model.changedAttributes();
@@ -769,21 +788,21 @@ var ModelTable = Table.extend({
         var self = this;
 
         var dialog = self.addDialog;
-        dialog.attributes = {};
+        dialog.entry = {};
 
         dialog.handler("add", function() {
 
             // save new attributes
             dialog.save();
-            var attributes = {};
-            _.each(dialog.attributes, function(value, key) {
+            var entry = {};
+            _.each(dialog.entry, function(value, key) {
                 if (value == "") return;
-                attributes[key] = value;
+                entry[key] = value;
             });
 
             // save new entry with POST
             var model = new self.collection.model();
-            model.save(attributes, {
+            model.save(entry, {
                 wait: true,
                 success: function(model, response, options) {
                     // redraw table after adding new entry
@@ -881,8 +900,8 @@ var EntryPage = Page.extend({
         var self = this;
 
         if (self.mode == "add") {
-            // Use empty attributes.
-            self.attributes = {};
+            // Use blank entry.
+            self.entry = {};
 
             // All fields are editable.
             self.$(".pki-fields input").each(function(index) {
@@ -891,11 +910,11 @@ var EntryPage = Page.extend({
             });
 
         } else {
-            // Use entry attributes.
-            self.attributes = _.clone(self.model.attributes);
+            // Use fetched entry.
+            self.entry = _.clone(self.model.attributes);
 
             // Show entry ID in the title.
-            self.$("span[name='id']").text(self.attributes.id);
+            self.$("span[name='id']").text(self.entry.id);
 
             if (self.mode == "edit") {
                 // Show editable fields.
@@ -935,7 +954,7 @@ var EntryPage = Page.extend({
     renderField: function(input) {
         var self = this;
         var name = input.attr("name");
-        var value = self.attributes[name];
+        var value = self.entry[name];
         if (value === undefined) value = "";
         input.val(value);
     },
@@ -955,7 +974,7 @@ var EntryPage = Page.extend({
 
         if (self.mode == "add") {
             // save new entry with POST
-            self.model.save(self.attributes, {
+            self.model.save(self.entry, {
                 wait: true,
                 success: function(model, response, options) {
                     self.close();
@@ -969,8 +988,8 @@ var EntryPage = Page.extend({
                 }
             });
         } else {
-            // save changed attributes with PATCH
-            self.model.save(self.attributes, {
+            // save changed entry with PATCH
+            self.model.save(self.entry, {
                 patch: true,
                 wait: true,
                 success: function(model, response, options) {
@@ -1000,9 +1019,9 @@ var EntryPage = Page.extend({
         var name = input.attr("name");
         var value = input.val();
         if (value == "") {
-            delete self.attributes[name];
+            delete self.entry[name];
         } else {
-            self.attributes[name] = value;
+            self.entry[name] = value;
         }
     }
 });
diff --git a/base/tps-tomcat/shared/webapps/tps/js/audit.js b/base/tps-tomcat/shared/webapps/tps/js/audit.js
index fc2bbdb1342641a70d4d0d62ba64d96c9677d1d9..b1ba21923982a46452cffdaf62ef3ef5fe1056c5 100644
--- a/base/tps-tomcat/shared/webapps/tps/js/audit.js
+++ b/base/tps-tomcat/shared/webapps/tps/js/audit.js
@@ -51,24 +51,22 @@ var AuditTableItem = TableItem.extend({
         var self = this;
         AuditTableItem.__super__.initialize.call(self, options);
     },
-    renderIDColumn: function(td) {
+    open: function(td) {
         var self = this;
 
         // in view mode all events are read-only
         if (self.table.mode == "view") {
-            self.renderColumn(td);
             return;
         }
 
         // mandatory events are read-only
         var value = self.get("value");
         if (value == "mandatory") {
-            self.renderColumn(td);
             return;
         }
 
         // optional events are editable in edit mode
-        AuditTableItem.__super__.renderIDColumn.call(self, td);
+        AuditTableItem.__super__.open.call(self, td);
     }
 });
 
@@ -123,7 +121,7 @@ var AuditPage = EntryPage.extend({
             self.eventsTable.mode = "view";
         }
 
-        self.eventsTable.entries = self.attributes.events;
+        self.eventsTable.entries = self.entry.events;
         self.eventsTable.render();
     },
     saveFields: function() {
@@ -131,6 +129,6 @@ var AuditPage = EntryPage.extend({
 
         AuditPage.__super__.saveFields.call(self);
 
-        self.attributes.events = self.eventsTable.entries;
+        self.entry.events = self.eventsTable.entries;
     }
 });
diff --git a/base/tps-tomcat/shared/webapps/tps/js/config.js b/base/tps-tomcat/shared/webapps/tps/js/config.js
index 3bd2492dfe2f197f5f0b377f36e9137c15f296e4..cbbd0affb50e72ddcd53ffbe3aae48580ebfe42c 100644
--- a/base/tps-tomcat/shared/webapps/tps/js/config.js
+++ b/base/tps-tomcat/shared/webapps/tps/js/config.js
@@ -40,25 +40,6 @@ var ConfigModel = Model.extend({
     }
 });
 
-var PropertiesTableItem = TableItem.extend({
-    initialize: function(options) {
-        var self = this;
-        PropertiesTableItem.__super__.initialize.call(self, options);
-    },
-    renderIDColumn: function(td) {
-        var self = this;
-
-        // in view mode all properties are read-only
-        if (self.table.mode == "view") {
-            self.renderColumn(td);
-            return;
-        }
-
-        // in edit mode all properties are editable
-        PropertiesTableItem.__super__.renderIDColumn.call(self, td);
-    }
-});
-
 var ConfigPage = EntryWithPropertiesPage.extend({
     initialize: function(options) {
         var self = this;
diff --git a/base/tps-tomcat/shared/webapps/tps/js/tps.js b/base/tps-tomcat/shared/webapps/tps/js/tps.js
index 16199cb4f46ed8bb471b821893b2a163494eacfc..09ea7e5ab3b35928eb7aeb08ec70cdd942b02bd6 100644
--- a/base/tps-tomcat/shared/webapps/tps/js/tps.js
+++ b/base/tps-tomcat/shared/webapps/tps/js/tps.js
@@ -19,6 +19,34 @@
  * @author Endi S. Dewata
  */
 
+var PropertiesTableItem = TableItem.extend({
+    initialize: function(options) {
+        var self = this;
+        PropertiesTableItem.__super__.initialize.call(self, options);
+    },
+    get: function(name) {
+        var self = this;
+
+        if (name.substring(0, 7) == "parent.") {
+            name = name.substring(7);
+            return self.table.parent.entry[name];
+        }
+
+        return PropertiesTableItem.__super__.get.call(self, name);
+    },
+    open: function(td) {
+        var self = this;
+
+        // in view mode all properties are read-only
+        if (self.table.mode == "view") {
+            return;
+        }
+
+        // in edit mode all properties are editable
+        PropertiesTableItem.__super__.open.call(self, td);
+    }
+});
+
 var PropertiesTable = Table.extend({
     initialize: function(options) {
         var self = this;
@@ -53,7 +81,7 @@ var EntryWithPropertiesPage = EntryPage.extend({
         var self = this;
         EntryWithPropertiesPage.__super__.initialize.call(self, options);
         self.parentPage = options.parentPage;
-        self.tableItem = options.tableItem;
+        self.tableItem = options.tableItem || PropertiesTableItem;
         self.tableSize = options.tableSize || 10;
     },
     setup: function() {
@@ -69,7 +97,7 @@ var EntryWithPropertiesPage = EntryPage.extend({
             if (!confirm(message)) return;
             self.model.enable({
                 success: function(data, textStatus, jqXHR) {
-                    self.attributes = _.clone(self.model.attributes);
+                    self.entry = _.clone(self.model.attributes);
                     self.render();
                 },
                 error: function(jqXHR, textStatus, errorThrown) {
@@ -83,7 +111,7 @@ var EntryWithPropertiesPage = EntryPage.extend({
             if (!confirm(message)) return;
             self.model.disable({
                 success: function(data, textStatus, jqXHR) {
-                    self.attributes = _.clone(self.model.attributes);
+                    self.entry = _.clone(self.model.attributes);
                     self.render();
                 },
                 error: function(jqXHR, textStatus, errorThrown) {
@@ -124,7 +152,8 @@ var EntryWithPropertiesPage = EntryPage.extend({
             editDialog: editDialog,
             viewDialog: viewDialog,
             tableItem: self.tableItem,
-            pageSize: self.tableSize
+            pageSize: self.tableSize,
+            parent: self
         });
     },
     renderContent: function() {
@@ -132,7 +161,7 @@ var EntryWithPropertiesPage = EntryPage.extend({
 
         EntryWithPropertiesPage.__super__.renderContent.call(self);
 
-        var status = self.attributes.status;
+        var status = self.entry.status;
         if (status == "Disabled") {
             self.enableLink.show();
             self.disableLink.hide();
@@ -147,11 +176,11 @@ var EntryWithPropertiesPage = EntryPage.extend({
 
         } else if (self.mode == "edit") {
             self.propertiesTable.mode = "edit";
-            self.propertiesTable.entries = self.attributes.properties;
+            self.propertiesTable.entries = self.entry.properties;
 
         } else { // self.mode == "view"
             self.propertiesTable.mode = "view";
-            self.propertiesTable.entries = self.attributes.properties;
+            self.propertiesTable.entries = self.entry.properties;
         }
 
         self.propertiesTable.render();
@@ -161,7 +190,7 @@ var EntryWithPropertiesPage = EntryPage.extend({
 
         EntryWithPropertiesPage.__super__.saveFields.call(self);
 
-        self.attributes.properties = self.propertiesTable.entries;
+        self.entry.properties = self.propertiesTable.entries;
     },
     close: function() {
         var self = this;
diff --git a/base/tps-tomcat/shared/webapps/tps/js/user.js b/base/tps-tomcat/shared/webapps/tps/js/user.js
index 326bd5374341f4585d5e0f0e87389bd4f8336a67..cf78a4aed5fb9bf6c8bb9232a89ee8b557964c1e 100644
--- a/base/tps-tomcat/shared/webapps/tps/js/user.js
+++ b/base/tps-tomcat/shared/webapps/tps/js/user.js
@@ -96,7 +96,7 @@ var UserDialog = Dialog.extend({
             return;
         }
 
-        var attributes = self.attributes.attributes;
+        var attributes = self.entry.attributes;
         if (attributes) {
             var value = attributes.tpsProfiles;
             input.val(value);
@@ -107,14 +107,14 @@ var UserDialog = Dialog.extend({
 
         var name = input.attr("name");
         if (name != "tpsProfiles") {
-            UserDialog.__super__.saveField.call(self, input, attributes);
+            UserDialog.__super__.saveField.call(self, input);
             return;
         }
 
-        var attributes = self.attributes.attributes;
+        var attributes = self.entry.attributes;
         if (attributes == undefined) {
             attributes = {};
-            self.attributes.attributes = attributes;
+            self.entry.attributes = attributes;
         }
         attributes.tpsProfiles = input.val();
     }
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/activities.html b/base/tps-tomcat/shared/webapps/tps/ui/activities.html
index 3074a555fb8260645270663d1d63feb90043d9ed..760cfebfe158483174c0166988ad15faa114e7fc 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/activities.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/activities.html
@@ -44,13 +44,13 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="activity_select" type="checkbox"><label for="activity_select">&nbsp;</label></td>
-        <td name="id">&nbsp;</td>
-        <td name="tokenID">&nbsp;</td>
-        <td name="userID">&nbsp;</td>
-        <td name="ip">&nbsp;</td>
-        <td name="operation">&nbsp;</td>
-        <td name="result">&nbsp;</td>
-        <td name="date">&nbsp;</td>
+        <td name="id"><a href="/tps/ui/activities/${id}">${id}</a></td>
+        <td name="tokenID">${tokenID}</td>
+        <td name="userID">${userID}</td>
+        <td name="ip">${ip}</td>
+        <td name="operation">${operation}</td>
+        <td name="result">${result}</td>
+        <td name="date">${date}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/audit.html b/base/tps-tomcat/shared/webapps/tps/ui/audit.html
index d74a7b5a76732e9166a1ac1476c2d7a5433045c9..afc16aee71c4f3196a872804d97d15a902c72c28 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/audit.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/audit.html
@@ -73,8 +73,8 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="events_select" type="checkbox"><label for="events_select">&nbsp;</label></td>
-        <td name="id" class="pki-property-name-column"><a href="#">&nbsp;</a></td>
-        <td name="value">&nbsp;</td>
+        <td name="id" class="pki-property-name-column"><a href="/tps/ui/audit/events/${id}">${id}</a></td>
+        <td name="value">${value}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/authenticator.html b/base/tps-tomcat/shared/webapps/tps/ui/authenticator.html
index 4c36552eba21f558539e03a516608b636981c12f..cec27bcefd5e80c83b00c915256665ecbd539fcf 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/authenticator.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/authenticator.html
@@ -70,8 +70,8 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="authenticator_select" type="checkbox"><label for="authenticator_select">&nbsp;</label></td>
-        <td name="id" class="pki-property-name-column"><a href="#">&nbsp;</a></td>
-        <td name="value">&nbsp;</td>
+        <td name="id" class="pki-property-name-column"><a href="/tps/ui/authenticators/${parent.id}/properties/${id}">${id}</a></td>
+        <td name="value">${value}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/authenticators.html b/base/tps-tomcat/shared/webapps/tps/ui/authenticators.html
index 1d8311779a0bbcbea38051a31ccd02b119eada32..14c68f7c58fe1cc90f0032495f06a2583416820e 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/authenticators.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/authenticators.html
@@ -41,8 +41,8 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="authenticator_select" type="checkbox"><label for="authenticator_select">&nbsp;</label></td>
-        <td name="id">&nbsp;</td>
-        <td name="status">&nbsp;</td>
+        <td name="id"><a href="/tps/ui/authenticators/${id}">${id}</a></td>
+        <td name="status">${status}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/certs.html b/base/tps-tomcat/shared/webapps/tps/ui/certs.html
index f15d9feca49ba773974657a73340c3ce94b6697d..11312fbc0c9b9803653be4d55df3678fffcc43cb 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/certs.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/certs.html
@@ -46,15 +46,15 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="cert_select" type="checkbox"><label for="cert_select">&nbsp;</label></td>
-        <td name="id">&nbsp;</td>
-        <td name="serialNumber">&nbsp;</td>
-        <td name="subject">&nbsp;</td>
-        <td name="tokenID">&nbsp;</td>
-        <td name="userID">&nbsp;</td>
-        <td name="keyType">&nbsp;</td>
-        <td name="status">&nbsp;</td>
-        <td name="createTime">&nbsp;</td>
-        <td name="modifyTime">&nbsp;</td>
+        <td name="id"><a href="/tps/ui/certs/${id}">${id}</a></td>
+        <td name="serialNumber">${serialNumber}</td>
+        <td name="subject">${subject}</td>
+        <td name="tokenID">${tokenID}</td>
+        <td name="userID">${userID}</td>
+        <td name="keyType">${keyType}</td>
+        <td name="status">${status}</td>
+        <td name="createTime">${createTime}</td>
+        <td name="modifyTime">${modifyTime}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/config.html b/base/tps-tomcat/shared/webapps/tps/ui/config.html
index 69dd06b12c18fb0fb95bcd162382597ae11e8ccb..54badf178766ebbf49c9143ee7271259c8f812e6 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/config.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/config.html
@@ -56,8 +56,8 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="properties_select" type="checkbox"><label for="properties_select">&nbsp;</label></td>
-        <td name="id" class="pki-property-name-column"><a href="#">&nbsp;</a></td>
-        <td name="value">&nbsp;</td>
+        <td name="id" class="pki-property-name-column"><a href="/tps/ui/config/properties/${id}">${id}</a></td>
+        <td name="value">${value}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/connection.html b/base/tps-tomcat/shared/webapps/tps/ui/connection.html
index ad8e64836399eff720bef6e9c8cdd61da59eff17..5cc809e9e03bb09196ea91732607e3bbc6a0c583 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/connection.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/connection.html
@@ -70,8 +70,8 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="connection_select" type="checkbox"><label for="connection_select">&nbsp;</label></td>
-        <td name="id" class="pki-property-name-column"><a href="#">&nbsp;</a></td>
-        <td name="value">&nbsp;</td>
+        <td name="id" class="pki-property-name-column"><a href="/tps/ui/connections/${parent.id}/properties/${id}">${id}</a></td>
+        <td name="value">${value}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/connections.html b/base/tps-tomcat/shared/webapps/tps/ui/connections.html
index 8b8c167191f13101ded6cb9fdac43020023d6663..59d64f7f3a2655216275e1ed6875c5230ff6c072 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/connections.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/connections.html
@@ -41,8 +41,8 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="connection_select" type="checkbox"><label for="connection_select">&nbsp;</label></td>
-        <td name="id">&nbsp;</td>
-        <td name="status">&nbsp;</td>
+        <td name="id"><a href="/tps/ui/connections/${id}">${id}</a></td>
+        <td name="status">${status}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/groups.html b/base/tps-tomcat/shared/webapps/tps/ui/groups.html
index 6a8b0192bbd29713bcfc4491acee2317daaf89e1..7bf9564cfab1273e9159b7a685b864d1e6f6483d 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/groups.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/groups.html
@@ -41,8 +41,8 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="group_select" type="checkbox"><label for="group_select">&nbsp;</label></td>
-        <td name="id">&nbsp;</td>
-        <td name="description">&nbsp;</td>
+        <td name="id"><a href="/tps/ui/groups/${id}">${id}</a></td>
+        <td name="description">${description}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/profile-mapping.html b/base/tps-tomcat/shared/webapps/tps/ui/profile-mapping.html
index 2af535bcebf103ec26e7829458aad8e26783122d..986780b2b4682e673bb0c731a827e1386ddf35dd 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/profile-mapping.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/profile-mapping.html
@@ -70,8 +70,8 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="profile_select" type="checkbox"><label for="profile_select">&nbsp;</label></td>
-        <td name="id" class="pki-property-name-column"><a href="#">&nbsp;</a></td>
-        <td name="value">&nbsp;</td>
+        <td name="id" class="pki-property-name-column"><a href="/tps/ui/profile-mappings/${parent.id}/properties/${id}">${id}</a></td>
+        <td name="value">${value}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/profile-mappings.html b/base/tps-tomcat/shared/webapps/tps/ui/profile-mappings.html
index c393446b1397e8bfdc207e8ddfa52eb2ca195907..fe651f2184da30740f283dc06687ce7b6a1c805c 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/profile-mappings.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/profile-mappings.html
@@ -41,8 +41,8 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="profile_mapping_select" type="checkbox"><label for="profile_mapping_select">&nbsp;</label></td>
-        <td name="id"><a href="profile-mapping.html">&nbsp;</a></td>
-        <td name="status">&nbsp;</td>
+        <td name="id"><a href="/tps/ui/profile-mappings/${id}">${id}</a></td>
+        <td name="status">${status}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/profile.html b/base/tps-tomcat/shared/webapps/tps/ui/profile.html
index 4cd2f1dba12e9d574034c9faf2251df55a7c1cd4..cdc42a2ab6066dc6a8a962198f7e2e17e55598f4 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/profile.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/profile.html
@@ -70,8 +70,8 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="profile_select" type="checkbox"><label for="profile_select">&nbsp;</label></td>
-        <td name="id" class="pki-property-name-column"><a href="#">&nbsp;</a></td>
-        <td name="value">&nbsp;</td>
+        <td name="id" class="pki-property-name-column"><a href="/tps/ui/profiles/${parent.id}/properties/${id}">${id}</a></td>
+        <td name="value">${value}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/profiles.html b/base/tps-tomcat/shared/webapps/tps/ui/profiles.html
index 99b7ac759741b134b1a411e6160770f9bec0c56a..2bcc3e04c99ab8f1cf0d266c6257583b70f3e6fb 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/profiles.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/profiles.html
@@ -41,8 +41,8 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="profile_select" type="checkbox"><label for="profile_select">&nbsp;</label></td>
-        <td name="id"><a href="profile.html">&nbsp;</a></td>
-        <td name="status">&nbsp;</td>
+        <td name="id"><a href="/tps/ui/profiles/${id}">${id}</a></td>
+        <td name="status">${status}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/selftests.html b/base/tps-tomcat/shared/webapps/tps/ui/selftests.html
index f9a7bdd45f013fced5a142d9b16ad3055a852903..cb3afb30e201f850eaad8e9a3c6bed2625b3b43d 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/selftests.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/selftests.html
@@ -42,11 +42,11 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="selftest_select" type="checkbox"><label for="selftest_select">&nbsp;</label></td>
-        <td name="id">&nbsp;</td>
-        <td name="enabledAtStartup">&nbsp;</td>
-        <td name="criticalAtStartup">&nbsp;</td>
-        <td name="enabledOnDemand">&nbsp;</td>
-        <td name="criticalOnDemand">&nbsp;</td>
+        <td name="id"><a href="/tps/ui/selftest/${id}">${id}</a></td>
+        <td name="enabledAtStartup">${enabledAtStartup}</td>
+        <td name="criticalAtStartup">${criticalAtStartup}</td>
+        <td name="enabledOnDemand">${enabledOnDemand}</td>
+        <td name="criticalOnDemand">${criticalOnDemand}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/tokens.html b/base/tps-tomcat/shared/webapps/tps/ui/tokens.html
index 16ab6b235d5ce4d41a5bc8ded2205d1aaa22c9dd..7a5c168350aa05716be2e021e294ece13d04aedb 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/tokens.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/tokens.html
@@ -47,14 +47,14 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="token_select" type="checkbox"><label for="token_select">&nbsp;</label></td>
-        <td name="id">&nbsp;</td>
-        <td name="userID">&nbsp;</td>
-        <td name="status">&nbsp;</td>
-        <td name="reason">&nbsp;</td>
-        <td name="appletID">&nbsp;</td>
-        <td name="keyInfo">&nbsp;</td>
-        <td name="created">&nbsp;</td>
-        <td name="modified">&nbsp;</td>
+        <td name="id"><a href="/tps/ui/tokens/${id}">${id}</a></td>
+        <td name="userID">${userID}</td>
+        <td name="status"><a href="/tps/ui/tokens/${id}/status">${status}</a></td>
+        <td name="reason">${reason}</td>
+        <td name="appletID">${appletID}</td>
+        <td name="keyInfo">${keyInfo}</td>
+        <td name="created">${created}</td>
+        <td name="modified">${modified}</td>
     </tr>
 </tbody>
 <tfoot>
diff --git a/base/tps-tomcat/shared/webapps/tps/ui/users.html b/base/tps-tomcat/shared/webapps/tps/ui/users.html
index 89ef686e261de14ee467bb7b38e1d98e367337b0..4190a0dde8bec3e49d425504fab2c1bfd9a334c1 100644
--- a/base/tps-tomcat/shared/webapps/tps/ui/users.html
+++ b/base/tps-tomcat/shared/webapps/tps/ui/users.html
@@ -41,8 +41,8 @@
 <tbody>
     <tr>
         <td class="pki-select-column"><input id="user_select" type="checkbox"><label for="user_select">&nbsp;</label></td>
-        <td name="id">&nbsp;</td>
-        <td name="fullName">&nbsp;</td>
+        <td name="id"><a href="/tps/ui/users/${id}">${id}</a></td>
+        <td name="fullName">${fullName}</td>
     </tr>
 </tbody>
 <tfoot>
-- 
1.8.4.2

