ATLAS-1927: UI updates in rendering of tag attributes

Signed-off-by: Madhan Neethiraj <madhan@apache.org>
diff --git a/dashboardv2/public/css/scss/tag.scss b/dashboardv2/public/css/scss/tag.scss
index fc0652b..39bc995 100644
--- a/dashboardv2/public/css/scss/tag.scss
+++ b/dashboardv2/public/css/scss/tag.scss
@@ -18,8 +18,7 @@
 
 //tag.scss
 .tag-tree {
-    padding: 0;
-    // overflow: auto;
+    padding: 0; // overflow: auto;
     li {
         list-style: none;
         cursor: pointer;
@@ -38,7 +37,7 @@
                     display: block
                 }
             }
-            > ul > li {
+            >ul>li {
                 line-height: 30px;
                 margin-left: -20px;
                 text-indent: 20px;
@@ -93,7 +92,7 @@
     cursor: pointer;
 }
 
-.input-group.attributes .form-control:focus + .input-group-addon {
+.input-group.attributes .form-control:focus+.input-group-addon {
     border-color: $color_bali_hai_approx;
 }
 
@@ -131,7 +130,7 @@
             background-color: $tag_color;
         }
     }
-    > .inputValue {
+    >.inputValue {
         padding: 5px;
         &:hover {
             color: $white;
@@ -345,7 +344,7 @@
     margin-top: 10px;
 }
 
-.popoverContainer .inputTag > .inputValue {
+.popoverContainer .inputTag>.inputValue {
     padding: 2px 5px;
     display: inline-block;
     width: 100px;
@@ -410,3 +409,32 @@
 .entityLink {
     font-size: 16px;
 }
+
+.mainAttrTable {
+    max-height: 180px;
+    overflow: auto;
+    overflow-x: hidden;
+}
+
+table.attriTable {
+    width: 100%;
+    td {
+        border: 1px solid #ddd;
+        padding: 5px 7px;
+        width: 50%;
+        &[data-type="int"],
+        &[data-type="long"],
+        &[data-type="float"],
+        &[data-type="byte"],
+        &[data-type="double"],
+        &[data-type="short"] {
+            text-align: right;
+        }
+    }
+    th {
+        text-align: center !important;
+        border: 1px solid #ddd;
+        padding: 5px 7px;
+        width: 50%;
+    }
+}
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
index c45755f..56379a4 100644
--- a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
+++ b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
@@ -104,7 +104,7 @@
              * @constructs
              */
             initialize: function(options) {
-                _.extend(this, _.pick(options, 'collection', 'id', 'entityDefCollection', 'typeHeaders', 'enumDefCollection'));
+                _.extend(this, _.pick(options, 'collection', 'id', 'entityDefCollection', 'typeHeaders', 'enumDefCollection', 'classificationDefCollection'));
                 this.bindEvents();
             },
             bindEvents: function() {
@@ -172,7 +172,8 @@
                         typeHeaders: this.typeHeaders,
                         entityDefCollection: this.entityDefCollection,
                         fetchCollection: this.fetchCollection.bind(that),
-                        enumDefCollection: this.enumDefCollection
+                        enumDefCollection: this.enumDefCollection,
+                        classificationDefCollection: this.classificationDefCollection
                     }
                     this.getEntityDef(obj);
                     this.renderTagTableLayoutView(obj);
diff --git a/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js b/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js
index 45cdd6b..bac8b4b 100644
--- a/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js
+++ b/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js
@@ -64,7 +64,7 @@
              * @constructs
              */
             initialize: function(options) {
-                _.extend(this, _.pick(options, 'entity', 'guid', 'term', 'entityName', 'fetchCollection', 'enumDefCollection'));
+                _.extend(this, _.pick(options, 'entity', 'guid', 'term', 'entityName', 'fetchCollection', 'enumDefCollection', 'classificationDefCollection'));
                 this.collectionObject = this.entity;
                 this.tagTermCollection = new VTagList();
                 var tagorterm = _.toArray(this.collectionObject.classifications),
@@ -133,16 +133,25 @@
                             sortable: false,
                             formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
                                 fromRaw: function(rawValue, model) {
-                                    var values = model.get('attributes'),
-                                        tagValue = 'NA';
-                                    if (!_.isEmpty(values)) {
-                                        var stringArr = [];
-                                        tagValue = "";
-                                        _.each(values, function(val, key) {
-                                            var attrName = "<span>" + _.escape(key) + ":" + _.escape(val) + "</span>";
-                                            stringArr.push(attrName);
+                                    var values = model.get('attributes');
+                                    var data = that.classificationDefCollection.findWhere({ 'name': model.get('typeName') });
+                                    var attributeDefs = Utils.getNestedSuperTypeObj({ data: data.toJSON(), collection: that.classificationDefCollection, attrMerge: true });
+                                    var tagValue = 'NA',
+                                        dataType;
+                                    if (!_.isEmpty(attributeDefs)) {
+                                        var stringValue = "";
+                                        _.each(_.sortBy(_.map(attributeDefs, function(obj) {
+                                            obj['sortKey'] = obj.name && _.isString(obj.name) ? obj.name.toLowerCase() : "-";
+                                            return obj;
+                                        }), 'sortKey'), function(sortedObj) {
+                                            var val = _.isNull(values[sortedObj.name]) ? "-" : values[sortedObj.name],
+                                                key = sortedObj.name;
+                                            if (sortedObj.typeName === "date") {
+                                                val = new Date(val)
+                                            }
+                                            stringValue += "<tr><td class='html-cell string-cell renderable'>" + _.escape(key) + "</td><td class='html-cell string-cell renderable' data-type=" + sortedObj.typeName + ">" + _.escape(val) + "</td>";
                                         });
-                                        tagValue += stringArr.join(", ");
+                                        tagValue = "<div class='mainAttrTable'><table class='attriTable'><tr><th class='html-cell string-cell renderable'>Name</th><th class='html-cell string-cell renderable'>Value</th>" + stringValue + "</table></div>";
                                     }
                                     return tagValue;
                                 }
@@ -248,4 +257,4 @@
             }
         });
     return TagDetailTableLayoutView;
-});
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/tag/addTagModalView.js b/dashboardv2/public/js/views/tag/addTagModalView.js
index 97d80bd..e240974 100644
--- a/dashboardv2/public/js/views/tag/addTagModalView.js
+++ b/dashboardv2/public/js/views/tag/addTagModalView.js
@@ -272,10 +272,10 @@
                     var typeName = Utils.getName(obj, 'typeName');
                     var typeNameValue = that.enumDefCollection.fullCollection.findWhere({ 'name': typeName });
                     if (typeNameValue) {
-                        var str = "<option disabled='disabled'" + (!that.tagModel ? 'selected' : '') + ">-- Select " + typeName + " --</option>";
+                        var str = '<option value=""' + (!that.tagModel ? 'selected' : '') + '>-- Select ' + typeName + " --</option>";
                         var enumValue = typeNameValue.get('elementDefs');
                         _.each(enumValue, function(key, value) {
-                            str += '<option ' + (that.tagModel && key.value === that.tagModel.attributes[name] ? 'selected' : '') + '>' + key.value + '</option>';
+                            str += '<option ' + ((that.tagModel && key.value === that.tagModel.attributes[name]) ? 'selected' : '') + '>' + key.value + '</option>';
                         })
                         that.ui.tagAttribute.append('<div class="form-group"><label>' + name + '</label>' + ' (' + typeName + ')' +
                             '<select class="form-control attributeInputVal attrName" data-key="' + name + '">' + str + '</select></div>');
@@ -286,7 +286,14 @@
                 });
                 that.$('input[data-type="date"]').each(function() {
                     if (!$(this).data('daterangepicker')) {
-                        var dateObj = { "singleDatePicker": true, "showDropdowns": true };
+                        var dateObj = {
+                            "singleDatePicker": true,
+                            "showDropdowns": true,
+                            "timePicker": true,
+                            locale: {
+                                format: 'MM/DD/YYYY h:mm A'
+                            }
+                        };
                         if (that.tagModel) {
                             var formatDate = Number(this.value);
                             dateObj["startDate"] = new Date(formatDate);