You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by su...@apache.org on 2015/12/18 11:44:03 UTC

[03/26] incubator-atlas git commit: ATLAS-279 UI not displaying results for certain successful select search queries (anilsg via shwethags)

ATLAS-279 UI not displaying results for certain successful select search queries (anilsg via shwethags)


Project: http://git-wip-us.apache.org/repos/asf/incubator-atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-atlas/commit/cc2d8860
Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/cc2d8860
Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/cc2d8860

Branch: refs/heads/branch-0.6-incubating
Commit: cc2d886022dd314ae951e0e1dc44a808e6bc31c9
Parents: 4aef164
Author: Shwetha GS <ss...@hortonworks.com>
Authored: Tue Dec 8 10:16:40 2015 +0530
Committer: Shwetha GS <ss...@hortonworks.com>
Committed: Tue Dec 8 10:16:40 2015 +0530

----------------------------------------------------------------------
 dashboard/README.md                             |   2 +-
 dashboard/public/css/common.css                 |  12 ++
 dashboard/public/css/tags.css                   |   9 +-
 dashboard/public/index.html                     |   5 +-
 dashboard/public/js/app.js                      |  30 ++-
 .../public/modules/details/detailsController.js |   6 +-
 .../public/modules/details/views/details.html   |  13 +-
 dashboard/public/modules/home/views/header.html |   4 +-
 .../modules/lineage/lineage_ioController.js     |  21 +-
 .../modules/navigation/navigationController.js  |   8 +-
 .../modules/navigation/views/navigation.html    |   2 +-
 .../public/modules/search/searchController.js   | 164 ++++++++++----
 .../public/modules/search/views/search.html     | 214 +++++++++----------
 .../tags/definition/definitionTagsController.js |  14 +-
 .../modules/tags/definition/views/add.html      |  10 +-
 .../tags/instance/createTagController.js        |  50 +++--
 .../tags/instance/instanceTagsController.js     |  74 ++++---
 .../modules/tags/instance/views/createTag.html  |   2 +-
 .../modules/tags/instance/views/tags.html       |  84 +++++---
 docs/src/site/twiki/Bridge-Hive.twiki           |  12 +-
 release-log.txt                                 |   1 +
 21 files changed, 476 insertions(+), 261 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/README.md
----------------------------------------------------------------------
diff --git a/dashboard/README.md b/dashboard/README.md
index 0957582..5285e19 100644
--- a/dashboard/README.md
+++ b/dashboard/README.md
@@ -28,7 +28,7 @@
 
 ```
 git clone $git-repo-url
-git checkout dal
+git checkout master
 cd dashboard/v2
 npm install
 grunt server

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/css/common.css
----------------------------------------------------------------------
diff --git a/dashboard/public/css/common.css b/dashboard/public/css/common.css
index 7f55c0c..aa6dd11 100644
--- a/dashboard/public/css/common.css
+++ b/dashboard/public/css/common.css
@@ -353,4 +353,16 @@ Tags on Home Page design
 .anchorAbsolute {
     position: absolute;
     right: 4px;
+}
+
+.addTag{
+   margin-top: -35px;
+}
+
+.tagAlign{
+    text-align: center;
+} 
+
+.h160 {
+    height: 160px !important;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/css/tags.css
----------------------------------------------------------------------
diff --git a/dashboard/public/css/tags.css b/dashboard/public/css/tags.css
index 3078d3d..69bfd52 100644
--- a/dashboard/public/css/tags.css
+++ b/dashboard/public/css/tags.css
@@ -17,7 +17,7 @@
  */
 
 .add-tag {
-  margin-top: -7px;
+  margin-top: -50px;
 }
 .inputs input{
 	height: 50px;
@@ -113,4 +113,11 @@
 }
 .tagsAdded{
   display: inline;
+}
+
+.noTags {
+  font-size: 24px;
+  font-weight: bold;
+  text-align: center;
+}
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/index.html
----------------------------------------------------------------------
diff --git a/dashboard/public/index.html b/dashboard/public/index.html
index 1b9b22a..2d0993f 100644
--- a/dashboard/public/index.html
+++ b/dashboard/public/index.html
@@ -44,9 +44,10 @@
 <header class="navbar navbar-static-top navbar-top" data-role="navigation">
     <div class="container" data-ng-include="'/modules/home/views/header.html'"></div>
 </header>
-<div class="content">
+<div class="content container">
     <div data-ng-include="'/modules/notification/views/notifications.html'"></div>
-    <div data-ui-view class="container"></div>
+    <div class="col-lg-2 padding0" data-ng-include="'/modules/navigation/views/navigation.html'" ng-class="leftNav ? 'hide' : ''" ></div>
+    <div data-ui-view class="ngView"></div>
 </div>
 <footer class="footer navbar-bottom">
     <div class="container">

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/js/app.js
----------------------------------------------------------------------
diff --git a/dashboard/public/js/app.js b/dashboard/public/js/app.js
index 3ef1794..b128ff1 100644
--- a/dashboard/public/js/app.js
+++ b/dashboard/public/js/app.js
@@ -15,7 +15,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 'use strict';
 
 angular.module('dgc', ['ngCookies',
@@ -81,4 +80,31 @@ angular.module('dgc').factory('lodash', ['$window',
     $rootScope.$on('$stateChangeStart', function() {
         d3.selectAll('.d3-tip').remove();
     });
-}]);
+
+    $rootScope.updateTags = function(added, obj) {
+        if (added) {
+            $rootScope.$broadcast('add_Tag', obj);
+        }
+    };
+
+    $rootScope.loadTraits = function() {
+        $rootScope.$broadcast('load_Traits');
+    };
+
+    $rootScope.$on('$stateChangeSuccess', function(evt, to, toParams, from) {
+        if (from.name !== '' && to.name === 'search' && to.name !== from.name && typeof to.parent === 'undefined' && typeof from.parent === 'undefined') {
+            $rootScope.loadTraits();
+        } else if (from.name === '' && to.name === 'search') {
+            $rootScope.loadTraits();
+        }
+
+        if (typeof to.parent === 'undefined') {
+            if (to.name !== 'search') { 
+                $rootScope.leftNav = true;
+            } else { 
+                $rootScope.leftNav = false;
+            }
+        }
+    });
+
+}]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/details/detailsController.js
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/details/detailsController.js b/dashboard/public/modules/details/detailsController.js
index d56b58e..65a4e40 100644
--- a/dashboard/public/modules/details/detailsController.js
+++ b/dashboard/public/modules/details/detailsController.js
@@ -27,11 +27,11 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop
             id: $stateParams.id
         }, function(data) {
             $scope.details = data;
-            console.log(data);
             $scope.schemas = data;
             $scope.tableName = data.values.name;
             $scope.isTable = (typeof data.typeName !== 'undefined' && data.typeName.toLowerCase().indexOf('table') !== -1) ? true : false;
             $scope.onActivate('io');
+            $scope.isTags = (typeof data.traits !== 'undefined' && typeof data.traits === 'object') ? true : false;
         });
 
         $scope.isNumber = angular.isNumber;
@@ -45,7 +45,7 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop
             });
         };
 
-        $scope.goDetails = function(id){
+        $scope.goDetails = function(id) {
             $state.go("details", {
                 id: id
             });
@@ -55,4 +55,4 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop
             $window.history.back();
         };
     }
-]);
+]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/details/views/details.html
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/details/views/details.html b/dashboard/public/modules/details/views/details.html
index c05e222..95cd098 100644
--- a/dashboard/public/modules/details/views/details.html
+++ b/dashboard/public/modules/details/views/details.html
@@ -72,13 +72,14 @@
 
                     </tr>
                     </tbody>
-                </table>
-                <ng-include  src="'/modules/tags/instance/views/tags.html'"/>
+                </table> 
             </tab>
-            <tab data-heading="Schema" data-ng-if="isTable"><ng-include src="'/modules/details/views/schema.html'"/></tab>
-            <!-- <tab data-heading="Output" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('outputs')"><ng-include data-table-type="outputs" src="'/modules/lineage/views/lineage.html'"/></tab>
-            <tab data-heading="Input"  data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('inputs')"><ng-include data-table-type="inputs" src="'/modules/lineage/views/lineage.html'"/></tab>
-            <tab data-heading="Lineage"  data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('io')"><ng-include data-table-type="io" src="'/modules/lineage_io/views/lineage_io.html'"/></tab> -->
+           <tab data-heading="Schema" data-ng-if="isTable">
+              <ng-include src="'/modules/details/views/schema.html'"/>
+            </tab>
+            <tab data-heading="Tags" data-ng-if="isTags">
+              <ng-include  src="'/modules/tags/instance/views/tags.html'"/>
+            </tab> 
         </tabset>
     </div>
 </div>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/home/views/header.html
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/home/views/header.html b/dashboard/public/modules/home/views/header.html
index 0d64257..3d137a7 100644
--- a/dashboard/public/modules/home/views/header.html
+++ b/dashboard/public/modules/home/views/header.html
@@ -24,7 +24,7 @@
             <span class="icon-bar"></span>
             <span class="icon-bar"></span>
         </button>
- <a data-ui-sref="search({ query: '' })" data-ui-sref-active="active" class="mainLogo">
+ <a data-ui-sref="search()" data-ui-sref-active="active" class="mainLogo">
    <!--  <img src="../img/ApacheAtlasLogo.png" /> -->
    Apache <b>Atlas</b>
  </a>
@@ -32,7 +32,7 @@
     <nav class="collapse navbar-collapse" data-collapse="isCollapsed" data-role="navigation">
         <ul class="navbar-nav nav pull-right menuBar" data-ng-if="isLoggedIn()">
             <li data-ui-sref-active="active">
-                 <a data-ui-sref="search({ query: '' })" class="menulink">Search</a>
+                 <a data-ui-sref="search()" class="menulink">Search</a>
             </li>
             <li data-ng-repeat="item in menu" data-ui-sref-active="active">
                 <a data-ui-sref="{{item.state}}">{{item.title}}</a>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/lineage/lineage_ioController.js
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/lineage/lineage_ioController.js b/dashboard/public/modules/lineage/lineage_ioController.js
index 0a49ed0..e7b2734 100644
--- a/dashboard/public/modules/lineage/lineage_ioController.js
+++ b/dashboard/public/modules/lineage/lineage_ioController.js
@@ -19,7 +19,9 @@
 
 angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$scope', '$state', '$stateParams', 'lodash', 'LineageResource', 'd3', 'DetailsResource', '$q',
     function($element, $scope, $state, $stateParams, _, LineageResource, d3, DetailsResource, $q) {
-        var guidsList = [];
+        var guidsList = [],
+            $$ = angular.element;
+
 
         function inVertObj(edgs) {
             var newEdgsObj = {};
@@ -31,7 +33,7 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
                 }
             });
             return newEdgsObj;
-        } 
+        }
 
         function getCombinedLineageData(tableData, callRender) {
             LineageResource.get({
@@ -71,7 +73,7 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
                                 if (callRender) {
                                     render();
                                 }
-                            }); 
+                            });
                     } else {
                         $scope.requested = false;
                     }
@@ -130,11 +132,10 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
                 if (!$scope.lineageData) {
                     if ($scope.requested) {
                         if ($scope.type === 'io') {
-                            console.log($scope.type);
                             getCombinedLineageData(lineageData, true);
                         } else {
                             getCombinedLineageData(lineageData, true);
-                        } 
+                        }
                     }
                 } else {
                     render();
@@ -305,7 +306,13 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
             tooltip = d3.tip()
                 .attr('class', 'd3-tip')
                 .html(function(d) {
-                    return '<pre class="alert alert-success">' + d.name + '</pre>';
+                    var toolTip = $$("<pre>").attr("class", "alert alert-success")
+                        .append($$("<p>").html('Name :<b>' + d.name + '</b>'));
+
+                    if (d.tip && d.tip.trim() !== "") {
+                        toolTip.append($$("<p>").html('Query: ' + d.tip));
+                    }
+                    return toolTip.prop("outerHTML");
                 });
 
             // define the baseSvg, attaching a class for styling and the zoomListener
@@ -597,7 +604,7 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
                     })
                     .text(function(d) {
                         var nameDis = (d.name.length > 15) ? d.name.substring(0, 15) + "..." : d.name;
-                        $(this).attr('title', d.name);
+                        $$(this).attr('title', d.name);
                         return nameDis;
                     })
                     .style("fill-opacity", 0);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/navigation/navigationController.js
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/navigation/navigationController.js b/dashboard/public/modules/navigation/navigationController.js
index a012885..4602923 100644
--- a/dashboard/public/modules/navigation/navigationController.js
+++ b/dashboard/public/modules/navigation/navigationController.js
@@ -15,17 +15,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 'use strict';
 
 angular.module('dgc.navigation').controller('NavigationController', ['$scope', 'NavigationResource',
     function($scope, NavigationResource) {
 
-        $scope.leftnav = NavigationResource.get();
         $scope.updateVar = function(event) {
             $scope.$$prevSibling.query = angular.element(event.target).text();
 
         };
 
+        $scope.$on('load_Traits', function() {
+            $scope.leftnav = NavigationResource.get();
+        });
+
     }
-]);
+]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/navigation/views/navigation.html
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/navigation/views/navigation.html b/dashboard/public/modules/navigation/views/navigation.html
index af19294..9b1a443 100644
--- a/dashboard/public/modules/navigation/views/navigation.html
+++ b/dashboard/public/modules/navigation/views/navigation.html
@@ -16,7 +16,7 @@
   ~ limitations under the License.
   -->
 
-<div data-ng-controller="NavigationController" class="mainTags">
+<div data-ng-controller="NavigationController" class="mainTags leftNavigation">
     <h4>Tags</h4>
     <div class="list-group">
         <a ng-repeat="nav in leftnav" ui-sref="search({ query: nav })" class="list-group-item limitSize" title="{{nav}}"><i class="fa fa-tag"></i> {{nav}} </a>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/search/searchController.js
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/search/searchController.js b/dashboard/public/modules/search/searchController.js
index 2a134d6..4e4dde7 100644
--- a/dashboard/public/modules/search/searchController.js
+++ b/dashboard/public/modules/search/searchController.js
@@ -15,7 +15,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 'use strict';
 
 angular.module('dgc.search').controller('SearchController', ['$scope', '$location', '$http', '$state', '$stateParams', 'lodash', 'SearchResource', 'DetailsResource', 'NotificationService',
@@ -29,6 +28,12 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio
         $scope.filteredResults = [];
         $scope.resultRows = [];
         $scope.resultType = '';
+        $scope.isObject = angular.isObject;
+        $scope.isString = angular.isString;
+        $scope.isArray = angular.isArray;
+        $scope.isNumber = angular.isNumber;
+        $scope.mapAttr = ['guid', 'typeName', 'owner', 'description', 'createTime', '$traits$', '$id$', 'comment', 'dataType'];
+
         $scope.setPage = function(pageNo) {
             $scope.currentPage = pageNo;
         };
@@ -39,40 +44,67 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio
             $scope.searchMessage = 'load-gif';
             $scope.$parent.query = query;
             SearchResource.search({
-                query: encodeURIComponent(query)
+                query: query
             }, function searchSuccess(response) {
+
                 $scope.resultCount = response.count;
                 $scope.results = response.results;
-                $scope.resultRows = $scope.results;
+                $scope.resultRows = ($scope.results && $scope.results.rows) ? $scope.results.rows : $scope.results;
+
                 $scope.totalItems = $scope.resultCount;
                 $scope.transformedResults = {};
                 $scope.dataTransitioned = false;
-                if (response.dataType && response.dataType.typeName.indexOf('__') === 0) {
-                    $scope.dataTransitioned = true;
-                    var attrDef = response.dataType.attributeDefinitions;
-                    angular.forEach(attrDef, function(value) {
-                        if (value.dataTypeName === '__IdType') {
-                            $scope.searchKey = value.name;
-                        }
-                    });
-                    $scope.transformedResults = $scope.filterResults();
-                } else {
-                    $scope.transformedResults = $scope.resultRows;
-                }
+
                 if ($scope.results) {
                     if (response.dataType) {
                         $scope.resultType = response.dataType.typeName;
+                    } else if (response.results.dataType) {
+                        $scope.resultType = response.results.dataType.typeName;
+                    } else if (typeof response.dataType === 'undefined') {
+                        $scope.resultType = "full text";
                     }
                     $scope.searchMessage = $scope.resultCount + ' results matching your search query ' + $scope.query + ' were found';
                 } else {
                     $scope.searchMessage = '0 results matching your search query ' + $scope.query + ' were found';
                 }
 
+                if (response.dataType && response.dataType.typeName && response.dataType.typeName.toLowerCase().indexOf('table') === -1) {
+                    $scope.dataTransitioned = true;
+                    var attrDef = response.dataType.attributeDefinitions;
+                    if (attrDef.length === 1) {
+                        $scope.searchKey = attrDef[0].name;
+                    } else {
+                        angular.forEach(attrDef, function(value) {
+                            if (value.dataTypeName === '__IdType') {
+                                $scope.searchKey = value.name;
+                            }
+                        });
+                        if ($scope.searchKey === undefined || $scope.searchKey === '') {
+                            $scope.searchKey = '';
+                        }
+                    }
+                    $scope.transformedResults = $scope.filterResults();
+                    $scope.transformedProperties = $scope.filterProperties();
+
+                } else if (typeof response.dataType === 'undefined') {
+                    $scope.dataTransitioned = true;
+                    $scope.searchKey = '';
+                    $scope.transformedResults = $scope.filterResults();
+                    $scope.transformedProperties = $scope.filterProperties();
+                } else if (response.dataType.typeName && response.dataType.typeName.toLowerCase().indexOf('table') !== -1) {
+                    $scope.searchKey = "Table";
+                    $scope.transformedResults = $scope.resultRows;
+                } else if (response.results.dataType && response.results.dataType.typeName && response.results.dataType.typeName.toLowerCase().indexOf('table') !== -1) {
+                    $scope.searchKey = "Table";
+                    $scope.transformedResults = $scope.resultRows;
+                }
+
                 $scope.$watch('currentPage + itemsPerPage', function() {
                     var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
                         end = begin + $scope.itemsPerPage;
-                    if ($scope.transformedResults) $scope.filteredResults = $scope.transformedResults.slice(begin, end);
-                    console.log($scope.filteredResults);
+                    if ($scope.transformedResults) {
+                        $scope.filteredResults = $scope.transformedResults.slice(begin, end);
+                    }
                     $scope.pageCount = function() {
                         return Math.ceil($scope.resultCount / $scope.itemsPerPage);
                     };
@@ -84,15 +116,73 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio
                 $scope.searchMessage = '0 results matching your search query ' + $scope.query + ' were found';
                 NotificationService.error('Error occurred during executing search query, error status code = ' + err.status + ', status text = ' + err.statusText, false);
             });
+            $state.go('search', {
+                query: query
+            }, {
+                location: 'replace'
+            });
         };
 
         $scope.filterResults = function() {
             var res = [];
-            angular.forEach($scope.resultRows, function(value) {
-                res.push(value[$scope.searchKey]);
-            });
+            if ($scope.searchKey !== '') {
+                angular.forEach($scope.resultRows, function(value) {
+                    res.push(value[$scope.searchKey]);
+                });
+            } else {
+                angular.forEach($scope.resultRows, function(value) {
+                    var objVal = {},
+                        curVal = value,
+                        onlyId = false;
+
+                    if (curVal.name) {
+                        objVal.name = curVal.name;
+                        delete curVal.name;
+                    }
+                    angular.forEach(curVal, function(vl, ky) {
+                        if ($scope.mapAttr.indexOf(ky) !== -1 || ky.indexOf('_col_') !== -1 || ky.toLowerCase().indexOf('name') !== -1) {
+                            if (ky === '$id$') {
+                                objVal.id = curVal[ky].id;
+                                onlyId = true;
+                            } else if (ky === '$traits$') {
+                                objVal[ky] = vl;
+                                objVal.Tools = objVal.id;
+                                onlyId = false;
+                            } else if (ky.indexOf('$') === -1) {
+                                objVal[ky] = vl;
+                                onlyId = false;
+                            }
+                        }
+                    });
+
+                    if (onlyId) {
+                        objVal.guid = objVal.id;
+                    }
+
+                    res.push(objVal);
+                });
+            }
             return res;
         };
+
+        $scope.filterProperties = function() {
+            var results = $scope.transformedResults,
+                pro = [];
+            if (results && results.length > 0) {
+                var result = results[0];
+                if (typeof result === 'object') {
+                    angular.forEach(result, function(value, key) {
+                        if (key.indexOf('$typeName$') === -1) {
+                            pro.push(key);
+                        }
+                    });
+                } else {
+                    pro.push($scope.searchKey);
+                }
+            }
+            return pro;
+        };
+
         $scope.doToggle = function($event, el) {
             this.isCollapsed = !el;
         };
@@ -102,24 +192,24 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio
             });
         };
         $scope.isTag = function(typename) {
-             
-            if ( typename.indexOf( "__tempQueryResultStruct" ) > -1 ) {
+
+            if (typename.indexOf("__tempQueryResultStruct") > -1 || $scope.searchKey === '') {
                 return true;
             } else {
                 return false;
-            } 
+            }
         };
         $scope.getResourceDataHome = function(event, id) {
             DetailsResource.get({
                 id: id
-            }, function(data) { 
-                    if ($scope.filteredResults !== null && Object.keys($scope.filteredResults).length > 0) {               
-                        angular.forEach($scope.filteredResults, function(obj, trait) {
-                            if ( obj.$id$.id.indexOf( id ) > -1 ) {
-                                 $scope.filteredResults[trait].$traits$ = data.traits;
-                            }
-                        });
-                    }
+            }, function(data) {
+                if ($scope.filteredResults !== null && Object.keys($scope.filteredResults).length > 0) {
+                    angular.forEach($scope.filteredResults, function(obj, trait) {
+                        if ((obj.$id$ && obj.$id$.id.indexOf(id) > -1) || (obj.id && obj.id.indexOf(id) > -1)) {
+                            $scope.filteredResults[trait].$traits$ = data.traits;
+                        }
+                    });
+                }
             });
         };
         $scope.$on('refreshResourceData', $scope.getResourceDataHome);
@@ -137,18 +227,10 @@ angular.module('dgc.search').controller('SearchController', ['$scope', '$locatio
             return res;
         };
         $scope.searchQuery = $location.search();
-         if ($location.search().query)
-             $scope.query = decodeURIComponent($location.search().query);
+        $scope.query = ($location.search()).query;
         if ($scope.query) {
 
             $scope.search($scope.query);
         }
-         $scope.goSearch = function(query) {
-           $state.go('search', {
-                query: encodeURIComponent(query)
-            }, {
-                location: 'replace'
-            });
-        };
     }
-]);
+]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/search/views/search.html
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/search/views/search.html b/dashboard/public/modules/search/views/search.html
index e355644..b905cb9 100644
--- a/dashboard/public/modules/search/views/search.html
+++ b/dashboard/public/modules/search/views/search.html
@@ -1,123 +1,107 @@
-<!--
-  ~ Licensed to the Apache Software Foundation (ASF) under one
-  ~ or more contributor license agreements.  See the NOTICE file
-  ~ distributed with this work for additional information
-  ~ regarding copyright ownership.  The ASF licenses this file
-  ~ to you under the Apache License, Version 2.0 (the
-  ~ "License"); you may not use this file except in compliance
-  ~ with the License.  You may obtain a copy of the License at
-  ~
-  ~     http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<div class="row">
-    <div class="col-lg-2 padding0" data-ng-include="'/modules/navigation/views/navigation.html'"></div>
 
-    <div class="col-lg-10 paddingR0">
-        <div class="row mainSearch">
-            <form class="col-lg-12" name="form" novalidate>
-                <div class="input-group">
-                    <input type="text" class="form-control" placeholder="Search: Table, DB, Column" data-ng-model="query" required/>
-                    <span class="input-group-btn">
-                        <button class="btn btn-success" type="submit" data-ng-disabled="form.$invalid"   ng-click="goSearch(query)">
-                            <i class="glyphicon glyphicon-search white "></i>
-                        </button>
-                    </span>
-                </div>
-            </form>
-        </div>
-        <div class="col-lg-12 padding0 searchresults">
-            <div ng-switch on="searchMessage">
-                <div ng-switch-when="load-gif" class="search-spinner"><img src="../img/spinner.gif" align="middle" /></div>
-                <div ng-switch-default><h4 ng-show="searchMessage" title="{{searchMessage}}" class="searchResultCount">{{searchMessage}}</h4></div>
+
+<!--
+   ~ Licensed to the Apache Software Foundation (ASF) under one
+   ~ or more contributor license agreements.  See the NOTICE file
+   ~ distributed with this work for additional information
+   ~ regarding copyright ownership.  The ASF licenses this file
+   ~ to you under the Apache License, Version 2.0 (the
+   ~ "License"); you may not use this file except in compliance
+   ~ with the License.  You may obtain a copy of the License at
+   ~
+   ~     http://www.apache.org/licenses/LICENSE-2.0
+   ~
+   ~ Unless required by applicable law or agreed to in writing, software
+   ~ distributed under the License is distributed on an "AS IS" BASIS,
+   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   ~ See the License for the specific language governing permissions and
+   ~ limitations under the License.
+   -->
+<div class="col-lg-10 paddingR0">
+   <div class="">
+      <div class="row mainSearch">
+         <form class="col-lg-12" name="form" novalidate>
+            <div class="input-group">
+               <input type="text" class="form-control" placeholder="Search: Table, DB, Column" data-ng-model="query" required/>
+               <span class="input-group-btn">
+               <button class="btn btn-success" type="submit" data-ng-disabled="form.$invalid" ui-sref="search({ query: query })">
+               <i class="glyphicon glyphicon-search white "></i>
+               </button>
+               </span>
             </div>
-            <div class="panel panel-default" ng-show='resultCount > 0'>
-              <table class="table table-bordered datatable" >
-                <thead>
+         </form>
+      </div>
+      <div class="col-lg-12 padding0 searchresults">
+         <div ng-switch on="searchMessage">
+            <div ng-switch-when="load-gif" class="search-spinner"><img src="../img/spinner.gif" align="middle" /></div>
+            <div ng-switch-default>
+               <h4 ng-show="searchMessage" title="{{searchMessage}}" class="tabsearchResult">{{searchMessage}}</h4>
+            </div>
+         </div>
+         <div class="panel panel-default" ng-show='resultCount > 0'>
+            <table class="table table-bordered datatable" >
+               <thead>
                   <tr ng-if="!isTag(resultType)">
-                    <th>Name</th>
-                    <th>Description</th>
-                    <th>Owner</th>
-                    <th>Tags</th>
-                    <th>Tools</th>
+                     <th>Name</th>
+                     <th>Description</th>
+                     <th>Owner</th>
+                     <th>Tags</th>
+                     <th>Tools</th>
                   </tr>
-                  <tr ng-if="isTag(resultType)">
-                    <th>Name</th>
-                    <th>Type</th>
-                  </tr>                  
-                </thead>
-
-                <tbody>
-                  <tr ng-if="!isTag(resultType)" ng-repeat="result in filteredResults">
-                    <td>
-                      <a data-ui-sref="details({id:result['$id$'].id || result.guid})">{{result.name || result.guid}}</a>
-                    </td>
-
-                    <td>
-                      {{result.description}}
-                    </td>
-
-                    <td>                    
-                      <span ng-repeat="(key, value) in filterSearchResults(result)">
-                          <span ng-if="key =='owner'">{{value}}</span>
-                      </span>
-                    </td>
-
-                    <td>
-                      <div ng-show="!dataTransitioned" class="wordBreak"><a class="tabsearchanchor" ng-repeat="(key, value) in result['$traits$']" data-ui-sref="search({query: key})" title="{{key}}">{{key}}<span> </span></a></div>
-                    </td>
-                    <td class="addTag"><img ng-src="img/addTag.png" tooltip="Add Tag" ng-click="openAddTagHome(result['$id$'].id || result.guid)"></td>
+                  <tr ng-if="isTag(resultType) && transformedProperties != undefined" >
+                     <th ng-repeat="prop in transformedProperties" ng-if="prop !== 'id'">
+                        {{(prop != '$traits$') ? prop : 'Tags'}}
+                     </th>
                   </tr>
-                  <tr ng-if="isTag(resultType)" ng-repeat="result in filteredResults">
-                    <td>
-                      <a data-ui-sref="details({id:result.guid})">{{result.guid}}</a>
-                    </td>
-
-                    <td>
-                      {{result.typeName}}
-                    </td>
+               </thead>
+               <tbody>
+                  <tr ng-if="!isTag(resultType) && isObject(result)" ng-repeat="result in filteredResults track by $index">
+                     <td>
+                        <a data-ui-sref="details({id:result['$id$'].id || result.guid})">{{result.name || result.guid}}</a>
+                     </td>
+                     <td>
+                        {{result.description}}
+                     </td>
+                     <td>                    
+                        <span ng-repeat="(key, value) in filterSearchResults(result)">
+                        <span ng-if="key =='owner'">{{value}}</span>
+                        </span>
+                     </td>
+                     <td>
+                        <div id="{{result['$id$'].id}}" ng-show="!dataTransitioned" class="wordBreak"><a class="tabsearchanchor" ng-repeat="(key, value) in result['$traits$']" data-ui-sref="search({query: key})" title="{{key}}">{{key}}<span> </span></a></div>
+                     </td>
+                     <td class="addTag"><img ng-src="img/addTag.png" tooltip="Add Tag" ng-click="openAddTagHome(result['$id$'].id || result.guid)"></td>
                   </tr>
-                </tbody>
-              </table>
-            </div>
-
-            <!-- <ul class="list-unstyled"  ng-show='resultCount > 0'>
+                  <tr ng-if="isTag(resultType)" ng-repeat="result in filteredResults track by $index">
+                     <td data-ng-if="isObject(result) && !isString(result) && res != 'id'" data-ng-repeat="res in transformedProperties track by $index">
+                        
+                        <a data-ng-if="res == 'guid'" data-ui-sref="details({id:result[res]})">{{result[res]}}</a>
+                        
+                        <span data-ng-if="res != '$traits$' && res != 'Tools' && res != 'guid' && res.toLowerCase().indexOf('name') == -1 && res.toLowerCase().indexOf('time') == -1">{{result[res]}}</span> 
+                        
+                        <span data-ng-if="res.toLowerCase().indexOf('time') != -1 && isNumber(result[res])">{{result[res] * 1000 | date:'yyyy-MM-dd HH:mm:ss'}} UTC</span> 
+                        
+                        <a data-ng-if="res.toLowerCase().indexOf('name') != -1" data-ui-sref="details({id:result['id']|| result['guid']})">{{result[res]}}</a>
+                        
+                        <div data-ng-if="res == '$traits$'" class="wordBreak tags" id="{{result['id']|| result['guid']}}">
+                           <a class="tabsearchanchor" ng-repeat="(key, value) in result[res]" data-ui-sref="search({query: key})" title="{{key}}">{{key}}<span> </span></a>
+                        </div>
+                        
+                        <span data-ng-if="res == 'Tools'" class="addTag"> <img ng-src="img/addTag.png" tooltip="Add Tag" ng-click="openAddTagHome(result['id']|| result['guid'])"> </span>
+                     </td>
+                     <td data-ng-if="isString(result) || result == false || result == true">
+                        <a data-ng-if="result.toLowerCase() == 'guid'" data-ui-sref="details({id:result})">{{result}}</a>
+                        <span data-ng-if="result.toLowerCase() != 'guid'">{{result}}</span>
+                     </td>
                   </tr>
-                </tbody>
-              </table>
-            </div>
-
-            <!-- <ul class="list-unstyled"  ng-show='resultCount > 0'>
-                <li ng-repeat="result in filteredResults" class="searchresults">
-                    <h4><a data-ui-sref="details({id:result['$id$'].id || result.guid})">{{result.name || result.guid}}</a></h4>
-
-                    <p>{{result.description}}</p>
-                    <span ng-repeat="(key, value) in filterSearchResults(result)">
-                        <span ng-show="$index <= 3  "><b>{{key}}: </b>{{value}} {{(($index+1 === limit) || $last ) ? '' : ', '}}</span>
-                    </span>
+               </tbody>
+            </table>
+         </div>
+         <div class="pull-right" ng-show='resultCount > 0'>
+            <pagination total-items="totalItems" items-per-page="itemsPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
+            <p>
+         </div>
+      </div>
+   </div>
+</div>
 
-                    <div collapse="isCollapsed">
-                      <span ng-repeat="(key, value) in filterSearchResults(result)">
-                        <span ng-show="$index > 3"><b>{{key}}: </b>{{value}}{{$last ? '' : ', '}}</span>
-                      </span>
-                    </div>
-                    <a href ng-show="isCollapsed && (keyLength > 4)" ng-click="doToggle($event,isCollapsed)">..show more</a>
-                    <a href ng-show="!isCollapsed" ng-click="doToggle($event,isCollapsed)">..show less</a>
-
-                    <h5 ng-show="!dataTransitioned">Tags : <a ng-repeat="(key, value) in result['$traits$']" data-ui-sref="search({query: key})">{{key}}<span ng-show="!{{$last}}">,</span> </a></h5>
-
-                </li>
-            </ul> -->
-
-            <div class="pull-right" ng-show='resultCount > 0'>
-                <pagination total-items="totalItems" items-per-page="itemsPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination>
-                <p>
-            </div>
-        </div>
-    </div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/tags/definition/definitionTagsController.js
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/tags/definition/definitionTagsController.js b/dashboard/public/modules/tags/definition/definitionTagsController.js
index a3e7ce6..15a6b42 100755
--- a/dashboard/public/modules/tags/definition/definitionTagsController.js
+++ b/dashboard/public/modules/tags/definition/definitionTagsController.js
@@ -15,24 +15,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 'use strict';
 
-angular.module('dgc.tags.definition').controller('DefinitionTagsController', ['$scope', '$resource', '$state', '$stateParams', 'lodash', 'AttributeDefinition', 'TagClasses', 'TagsResource', 'NotificationService',
-    function($scope, $resource, $state, $stateParams, _, AttributeDefinition, Categories, TagsResource, NotificationService) {
+angular.module('dgc.tags.definition').controller('DefinitionTagsController', ['$scope', '$resource', '$state', '$stateParams', 'lodash', 'AttributeDefinition', 'TagClasses', 'TagsResource', 'NotificationService', 'NavigationResource',
+    function($scope, $resource, $state, $stateParams, _, AttributeDefinition, Categories, TagsResource, NotificationService, NavigationResource) {
         $scope.categoryList = Categories;
         $scope.category = 'TRAIT';
         $scope.tagModel = {
             typeName: null,
+            superTypes: [],
             attributeDefinitions: []
         };
+        $scope.typesList = NavigationResource.get();
 
         $scope.addAttribute = function AddAttribute() {
             $scope.tagModel.attributeDefinitions.push(AttributeDefinition.getModel());
         };
 
-        $scope.removeAttribute = function(index){
-            $scope.tagModel.attributeDefinitions.splice(index,1);
+        $scope.removeAttribute = function(index) {
+            $scope.tagModel.attributeDefinitions.splice(index, 1);
         };
 
         $scope.categoryChange = function CategorySwitched() {
@@ -42,6 +43,7 @@ angular.module('dgc.tags.definition').controller('DefinitionTagsController', ['$
         $scope.save = function saveTag(form) {
             $scope.savedTag = null;
             if (form.$valid) {
+                $scope.tagModel.superTypes = $scope.selectedParent;
                 $scope.categoryInst = Categories[$scope.category];
                 $scope.categoryInst.clearTags().addTag($scope.tagModel);
 
@@ -59,4 +61,4 @@ angular.module('dgc.tags.definition').controller('DefinitionTagsController', ['$
             }
         };
     }
-]);
+]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/tags/definition/views/add.html
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/tags/definition/views/add.html b/dashboard/public/modules/tags/definition/views/add.html
index dcdd27d..fdcc6d8 100755
--- a/dashboard/public/modules/tags/definition/views/add.html
+++ b/dashboard/public/modules/tags/definition/views/add.html
@@ -39,6 +39,14 @@
                           <input type="text" class="form-control" name="typeName" id="typeName" placeholder="Tag Name" data-ng-model="tagModel.typeName" required/>
                       </div>
                   </div>
+                  <div class="form-group">
+                     <label class="control-label col-sm-2" for="ParentTag">Parent Tag</label>
+                      <div class="col-sm-4">
+                          <select ng-model="selectedParent" class="form-control h160" id="ParentTag" name="ParentTag" multiple> 
+                              <option ng-repeat="data in typesList" title="{{data}}">{{data}}</option>
+                          </select>
+                      </div>
+                  </div>
                   <ng-form name="attributeForm">
                       <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}"
                            data-ng-repeat-start="attribute in tagModel.attributeDefinitions">
@@ -55,7 +63,7 @@
                           </div>
                       </div>
                       <div class="form-group" data-ng-class="{'has-error': attributeForm.name.$invalid && attributeForm.name.$dirty}" data-ng-show="attribute.$$show">
-                          <label for="attributeDatatype_{{$index}}" class="col-sm-2 control-label">Data Type Name</label>
+                          <label for="attributeDatatype_{{$index}}" class="col-sm-2 control-label">Data Type </label>
 
                           <div class="col-sm-10">
                               <input type="text" class="form-control" name="name" id="attributeDatatype_{{$index}}" placeholder="dataTypeName"

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/tags/instance/createTagController.js
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/tags/instance/createTagController.js b/dashboard/public/modules/tags/instance/createTagController.js
index 7cfc392..ba564c9 100644
--- a/dashboard/public/modules/tags/instance/createTagController.js
+++ b/dashboard/public/modules/tags/instance/createTagController.js
@@ -15,7 +15,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 'use strict';
 
 angular.module('dgc.tags.instance').controller('CreateTagController', ['$scope', 'DetailsResource', '$modalInstance', 'typesList', 'lodash', 'TagsResource', '$stateParams', '$rootScope', 'TagClasses', 'NotificationService',
@@ -23,29 +22,44 @@ angular.module('dgc.tags.instance').controller('CreateTagController', ['$scope',
         if (typesList) {
             $scope.typesList = typesList;
         }
+        var $$ = angular.element;
         $scope.categoryList = Categories;
         $scope.category = 'TRAIT';
 
         $scope.getAttributeDefinations = function() {
+            $scope.propertiesList = {};
+            $scope.isRequired = {};
+            $scope.getAttributeApi($scope.selectedType);
+        };
+
+        $scope.getAttributeApi = function(tagName) {
             TagsResource.get({
-                id: $scope.selectedType
+                id: tagName
             }, function(data) {
                 var instanceType = Categories[$scope.category].instanceInfo();
                 if (instanceType) {
-                    var traitTypes = angular.fromJson(data.definition)[instanceType][0];
-                    if (traitTypes) {
-                        $scope.propertiesList = {};
-                        $scope.isRequired = {};
-                        _.each(traitTypes.attributeDefinitions, function(value) {
-                            $scope.propertiesList[value.name] = '';
-                            $scope.isRequired[value.name] = value.isRequired;
-                        });
+                    var traitTypes = angular.fromJson(data.definition)[instanceType];
+
+                    for (var t = 0; t < traitTypes.length; t++) {
+                        if (traitTypes[t]) {
+                           for(var indx = 0; indx < traitTypes[t].attributeDefinitions.length; indx++)
+                            { 
+                                var attrDefn = traitTypes[t].attributeDefinitions[indx];
+                                $scope.propertiesList[attrDefn.name] = '';
+                                $scope.isRequired[attrDefn.name] = attrDefn.isRequired;
+                            }
+                        }
+
+                        if (traitTypes[t].superTypes && traitTypes[t].superTypes.length > 0) {
+                            for (var s = 0; s < traitTypes[t].superTypes.length; s++) {
+                                $scope.getAttributeApi(traitTypes[t].superTypes[s]);
+                            }
+                        }
                     }
                 }
-
             });
         };
-        $scope.ok = function(tagDefinitionform) {
+        $scope.ok = function($event, tagDefinitionform) {
             if (tagDefinitionform.$valid) {
                 var requestObject = {
                     "jsonClass": "org.apache.atlas.typesystem.json.InstanceSerialization$_Struct",
@@ -54,8 +68,14 @@ angular.module('dgc.tags.instance').controller('CreateTagController', ['$scope',
                 };
                 DetailsResource.saveTag({
                     id: $stateParams.id
-                }, requestObject).$promise.then(function() {
-                    $rootScope.$broadcast('refreshResourceData', $stateParams.id);
+                }, requestObject).$promise.then(function(data) {
+                    if (data.requestId !== undefined && data.GUID === $stateParams.id) {
+                        var tagName = $$("#tagDefinition").val();
+                        $rootScope.updateTags(true, {
+                            added: $scope.selectedType
+                        });
+                        $$("#" + $stateParams.id).append("<a class='tabsearchanchor ng-binding ng-scope' data-ui-sref='search({query: " + tagName + "})' title='" + tagName + "' href='#!/search?query=" + tagName + "'>" + tagName + "<span> </span></a>");
+                    }
                     NotificationService.info('Tag "' + $scope.selectedType + '" has been added to entity', true);
                     $modalInstance.close(true);
                 }).catch(function(err) {
@@ -69,4 +89,4 @@ angular.module('dgc.tags.instance').controller('CreateTagController', ['$scope',
             $modalInstance.dismiss('cancel');
         };
     }
-]);
+]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/tags/instance/instanceTagsController.js
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/tags/instance/instanceTagsController.js b/dashboard/public/modules/tags/instance/instanceTagsController.js
index d1f3506..754f2cb 100644
--- a/dashboard/public/modules/tags/instance/instanceTagsController.js
+++ b/dashboard/public/modules/tags/instance/instanceTagsController.js
@@ -15,34 +15,50 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 'use strict';
 
 angular.module('dgc.tags.instance').controller('InstanceTagController', ['$scope', 'DetailsResource', '$stateParams', '$state',
     function($scope, DetailsResource, $stateParams, $state) {
         $scope.id = $stateParams.id;
+        var $$ = angular.element;
 
         function getResourceData() {
             DetailsResource.get({
                 id: $stateParams.id
             }, function(data) {
 
-                    angular.forEach(data.traits, function(obj, trait) {
-                        var pair_arr = [];
-                        if (obj.values !== null && Object.keys(obj.values).length > 0) {
-                            angular.forEach(obj.values, function(value, key) {
-                                   var pair = key+":"+value;
-                                   pair_arr.push(pair);                                
-                            });
-                            data.traits[trait].values = pair_arr.join(" | ");
-                        } else {
-                            data.traits[trait].values = 'NA';
-                        }
-                    });
-                
+                angular.forEach(data.traits, function(obj, trait) {
+                    var pair_arr = [];
+                    if (obj.values !== null && Object.keys(obj.values).length > 0) {
+                        angular.forEach(obj.values, function(value, key) {
+                            var pair = key + ":" + value;
+                            pair_arr.push(pair);
+                        });
+                        data.traits[trait].values = pair_arr.join(" | ");
+                    } else {
+                        data.traits[trait].values = 'NA';
+                    }
+                });
+
                 $scope.traitsList = data.traits;
+                if ($.isEmptyObject($scope.traitsList)) {
+                    $scope.noTags = true;
+                }
             });
         }
+
+        $scope.$on('add_Tag', function(evt, obj) {
+            $scope.traitsList[obj.added] = {
+                typeName: obj.added
+            };
+            if ($.isEmptyObject($scope.traitsList)) {
+                $scope.noTags = true;
+            } else {
+                $scope.noTags = false;
+            }
+        });
+
+
         $scope.openAddTag = function() {
             $state.go('addTag', {
                 id: $scope.id
@@ -50,25 +66,35 @@ angular.module('dgc.tags.instance').controller('InstanceTagController', ['$scope
         };
 
         $scope.detachTag = function($event, name) {
-            var r = confirm("Please confirm delete.");
-            if (r === true) {
+            $scope.displayName = name;
+            $$('#btnDelete').modal().on('click', function(e) {
+                e.preventDefault();
+                $$("#myModal").modal();
+
                 DetailsResource.detachTag({
                     id: $stateParams.id,
                     tagName: name
                 }, function(data) {
-                    console.log("Detached Tag");
-                    console.log(data);
 
                     if (data.requestId !== undefined && data.GUID === $stateParams.id && data.traitName === name) {
-                        var curent = $event.currentTarget;
-                        curent.parentElement.remove();
-                        $(".popover").remove();
+                        $$($event.currentTarget).closest('tr').remove();
+                        delete $scope.traitsList[name];
+                        if ($.isEmptyObject($scope.traitsList)) {
+                            $scope.noTags = true;
+                        } else {
+                            $scope.noTags = false;
+                        }
                     }
+
                 });
-            }
+            });
+        };
+
+        $scope.cancel = function() {
+            $$(".modal-backdrop").remove();
         };
-        
+
         getResourceData();
         $scope.$on('refreshResourceData', getResourceData);
     }
-]);
+]);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/tags/instance/views/createTag.html
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/tags/instance/views/createTag.html b/dashboard/public/modules/tags/instance/views/createTag.html
index a057894..2184b56 100644
--- a/dashboard/public/modules/tags/instance/views/createTag.html
+++ b/dashboard/public/modules/tags/instance/views/createTag.html
@@ -52,7 +52,7 @@
 			</div>
 		</div>
 		<div class="modal-footer">
-			<button class="btn btn-success" type="submit" ng-click="ok(tagDefinitionform)" ng-disabled="tagDefinitionform.$invalid">Save</button>
+			<button class="btn btn-success" type="submit" ng-click="ok($event, tagDefinitionform)" ng-disabled="tagDefinitionform.$invalid">Save</button>
 			<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
 		</div>
 	</form>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/dashboard/public/modules/tags/instance/views/tags.html
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/tags/instance/views/tags.html b/dashboard/public/modules/tags/instance/views/tags.html
index 40eccd5..6de1081 100644
--- a/dashboard/public/modules/tags/instance/views/tags.html
+++ b/dashboard/public/modules/tags/instance/views/tags.html
@@ -1,27 +1,63 @@
+
+
 <!--
-  ~ Licensed to the Apache Software Foundation (ASF) under one
-  ~ or more contributor license agreements.  See the NOTICE file
-  ~ distributed with this work for additional information
-  ~ regarding copyright ownership.  The ASF licenses this file
-  ~ to you under the Apache License, Version 2.0 (the
-  ~ "License"); you may not use this file except in compliance
-  ~ with the License.  You may obtain a copy of the License at
-  ~
-  ~     http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<div data-ng-controller="InstanceTagController">
-  <div class="container tag-list wordBreak">
-    <h4 class="tagsAdded">Tags</h4>
-    <a ng-click="openAddTag()" href="" class="add-tag btn btn-primary pull-right">Add tag</a>
-    <ul class="tagalign">
-      <li ng-repeat="trait in traitsList" class="list-group-item pointer tabsearchanchor maxwidth125px" popover="{{trait.values}}" popover-title="{{trait.typeName}} Values" popover-trigger="mouseenter" >
-        {{trait.typeName}} <a href="" class="anchorAbsolute" ng-click="detachTag($event, trait.typeName)"> <i class="fa fa-times"></i> </a> </li>
-    </ul>
+   ~ Licensed to the Apache Software Foundation (ASF) under one
+   ~ or more contributor license agreements.  See the NOTICE file
+   ~ distributed with this work for additional information
+   ~ regarding copyright ownership.  The ASF licenses this file
+   ~ to you under the Apache License, Version 2.0 (the
+   ~ "License"); you may not use this file except in compliance
+   ~ with the License.  You may obtain a copy of the License at
+   ~
+   ~     http://www.apache.org/licenses/LICENSE-2.0
+   ~
+   ~ Unless required by applicable law or agreed to in writing, software
+   ~ distributed under the License is distributed on an "AS IS" BASIS,
+   ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   ~ See the License for the specific language governing permissions and
+   ~ limitations under the License.
+   -->
+<div data-ng-controller="InstanceTagController" >
+   <div>
+      <a ng-click="openAddTag()" class="add-tag btn btn-primary pull-right">Add Tag</a>
+   </div>
+   <table class="table table-bordered">
+      <thead>
+         <tr>
+            <th>Tag</th>
+            <th>Tools</th>
+         </tr>
+      </thead>
+      <tbody>
+           <tr ng-repeat="trait in traitsList" class="pointer" ng-if="!noTags">
+            <td class="col-lg-11" >
+               {{trait.typeName}}
+            </td>
+            <td class="col-lg-1 tagAlign">
+               <a href="" class="deleteTag confirm-delete" data-toggle="modal" data-target="#myModal" ><i class="fa fa-trash-o " ng-click="detachTag($event, trait.typeName)"></i></a>
+            </td>
+         </tr>
+      </tbody>
+   </table>
+  <!-- Modal -->
+  <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+    <div class="modal-dialog" role="document">
+      <div class="modal-content">
+        <div class="modal-header">
+          <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+          <h4 class="modal-title" id="myModalLabel">Are you sure you want to delete ? </h4>
+        </div>
+        <div class="modal-body">
+            <b> Tag : {{displayName}} </b>
+        </div>
+        <div class="modal-footer">
+          <button type="button" class="btn btn-default" data-dismiss="modal" ng-click="cancel()">Close</button>
+          <button type="button" id="btnDelete" class="btn btn-primary" data-dismiss="modal">Delete</button>
+        </div>
+      </div>
+    </div>
   </div>
+  <div ng-if="noTags" class="noTags"> 
+      No tags to display 
+  </div>  
 </div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/docs/src/site/twiki/Bridge-Hive.twiki
----------------------------------------------------------------------
diff --git a/docs/src/site/twiki/Bridge-Hive.twiki b/docs/src/site/twiki/Bridge-Hive.twiki
index 34f82a5..86bdd7e 100644
--- a/docs/src/site/twiki/Bridge-Hive.twiki
+++ b/docs/src/site/twiki/Bridge-Hive.twiki
@@ -19,12 +19,12 @@ hive_partition(ClassType) - super types [Referenceable] - attributes [values, ta
 hive_process(ClassType) - super types [Process] - attributes [startTime, endTime, userName, operationType, queryText, queryPlan, queryId, queryGraph]
 </verbatim>
 
-The entities are created and de-duped using unique qualified name. They provide namespace and can be used for querying/lineage as well. Note that dbName and tableName should be in lower case. clusterName is explained below:
-hive_db - attribute qualifiedName - <dbName>@<clusterName>
-hive_table - attribute name - <dbName>.<tableName>@<clusterName>
-hive_column - attribute qualifiedName - <dbName>.<tableName>.<columnName>@<clusterName>
-hive_partition - attribute qualifiedName - <dbName>.<tableName>.<partitionValues('-' separated)>@<clusterName>
-hive_process - attribute name - <queryString> - trimmed query string in lower case
+The entities are created and de-duped using unique qualified name. They provide namespace and can be used for querying/lineage as well. Note that dbName and tableName should be in lower case. clusterName is explained below.
+   * hive_db - attribute qualifiedName - <dbName>@<clusterName>
+   * hive_table - attribute name - <dbName>.<tableName>@<clusterName>
+   * hive_column - attribute qualifiedName - <dbName>.<tableName>.<columnName>@<clusterName>
+   * hive_partition - attribute qualifiedName - <dbName>.<tableName>.<partitionValues('-' separated)>@<clusterName>
+   * hive_process - attribute name - <queryString> - trimmed query string in lower case
 
 
 ---++ Importing Hive Metadata

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/cc2d8860/release-log.txt
----------------------------------------------------------------------
diff --git a/release-log.txt b/release-log.txt
index b773bfb..979bdf2 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -9,6 +9,7 @@ ATLAS-54 Rename configs in hive hook (shwethags)
 ATLAS-3 Mixed Index creation fails with Date types (sumasai via shwethags)
 
 ALL CHANGES:
+ATLAS-279 UI not displaying results for certain successful "select" search queries (anilsg via shwethags)
 ATLAS-242 The qualified name for hive entities should be backward compatible (shwethags)
 ATLAS-361 Add validation when index backends are switched in ATLAS configuration (sumasai via shwethags)
 ATLAS-171 Ability to update type definition(shwethags via sumasai)