You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by sa...@apache.org on 2019/10/10 18:43:28 UTC

[atlas] branch branch-2.0 updated (f0c117f -> 8f056d9)

This is an automated email from the ASF dual-hosted git repository.

sarath pushed a change to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/atlas.git.


    from f0c117f  ATLAS-3453: UI: show shell icon in entity detail page if status is incomplete
     new 4ba0a33  ATLAS:3456 : Allows user to add label in entity detail page.
     new 8f056d9  ATLAS-3455 :UI: Change shell icon and add shell icon in search table

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 dashboardv2/public/css/scss/common.scss            |  13 ++-
 dashboardv2/public/css/scss/graph.scss             |  27 -----
 dashboardv2/public/css/scss/panel.scss             |  16 +--
 dashboardv2/public/css/scss/table.scss             |  75 +++++++++++++
 dashboardv2/public/css/scss/theme.scss             |  80 +++++++++++---
 dashboardv2/public/js/models/VEntity.js            |  10 +-
 .../detail_page/DetailPageLayoutView_tmpl.html     |   1 +
 .../entity/EntityLabelDefineView_tmpl.html         |  97 +++++++++++++++++
 .../js/templates/graph/LineageLayoutView_tmpl.html |   2 +-
 .../templates/search/AdvancedSearchInfo_tmpl.html  |   2 +-
 .../public/js/templates/site/Statistics_tmpl.html  |  10 +-
 dashboardv2/public/js/utils/UrlLinks.js            |   5 +-
 .../js/views/detail_page/DetailPageLayoutView.js   |  12 ++-
 .../js/views/entity/EntityDetailTableLayoutView.js |   2 +-
 .../js/views/entity/EntityLabelDefineView.js       | 120 +++++++++++++++++++++
 .../public/js/views/entity/EntityUserDefineView.js |   2 +-
 .../public/js/views/graph/LineageLayoutView.js     |   5 +-
 .../js/views/search/SearchResultLayoutView.js      |  30 +++++-
 dashboardv3/public/css/scss/common.scss            |  13 ++-
 dashboardv3/public/css/scss/graph.scss             |  27 -----
 dashboardv3/public/css/scss/panel.scss             |  16 +--
 dashboardv3/public/css/scss/theme.scss             |  81 +++++++++++---
 dashboardv3/public/js/models/VEntity.js            |  10 +-
 .../detail_page/DetailPageLayoutView_tmpl.html     |   1 +
 .../entity/EntityLabelDefineView_tmpl.html         |  97 +++++++++++++++++
 .../js/templates/graph/LineageLayoutView_tmpl.html |   2 +-
 .../public/js/templates/site/Statistics_tmpl.html  |  10 +-
 dashboardv3/public/js/utils/UrlLinks.js            |   5 +-
 .../js/views/detail_page/DetailPageLayoutView.js   |  10 +-
 .../js/views/entity/EntityDetailTableLayoutView.js |   2 +-
 .../js/views/entity/EntityLabelDefineView.js       | 120 +++++++++++++++++++++
 .../public/js/views/entity/EntityUserDefineView.js |   2 +-
 .../public/js/views/graph/LineageLayoutView.js     |   5 +-
 .../js/views/search/SearchResultLayoutView.js      |   8 +-
 34 files changed, 783 insertions(+), 135 deletions(-)
 create mode 100644 dashboardv2/public/js/templates/entity/EntityLabelDefineView_tmpl.html
 create mode 100644 dashboardv2/public/js/views/entity/EntityLabelDefineView.js
 create mode 100644 dashboardv3/public/js/templates/entity/EntityLabelDefineView_tmpl.html
 create mode 100644 dashboardv3/public/js/views/entity/EntityLabelDefineView.js


[atlas] 02/02: ATLAS-3455 :UI: Change shell icon and add shell icon in search table

Posted by sa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sarath pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/atlas.git

commit 8f056d9eec3e97c72d8e27a4f9bb503e56af527f
Author: kevalbhatt <kb...@apache.org>
AuthorDate: Thu Oct 10 11:27:59 2019 -0700

    ATLAS-3455 :UI: Change shell icon and add shell icon in search table
    
    (cherry picked from commit a2de206015949b9b19e38058234a42d42ff0f0a1)
---
 dashboardv2/public/css/scss/graph.scss             | 27 --------
 dashboardv2/public/css/scss/table.scss             | 75 ++++++++++++++++++++
 dashboardv2/public/css/scss/theme.scss             | 80 +++++++++++++++++----
 .../js/templates/graph/LineageLayoutView_tmpl.html |  2 +-
 .../templates/search/AdvancedSearchInfo_tmpl.html  |  2 +-
 .../public/js/views/graph/LineageLayoutView.js     |  5 +-
 .../js/views/search/SearchResultLayoutView.js      | 30 +++++++-
 dashboardv3/public/css/scss/graph.scss             | 27 --------
 dashboardv3/public/css/scss/theme.scss             | 81 ++++++++++++++++++----
 .../js/templates/graph/LineageLayoutView_tmpl.html |  2 +-
 .../public/js/views/graph/LineageLayoutView.js     |  5 +-
 .../js/views/search/SearchResultLayoutView.js      |  8 ++-
 12 files changed, 250 insertions(+), 94 deletions(-)

diff --git a/dashboardv2/public/css/scss/graph.scss b/dashboardv2/public/css/scss/graph.scss
index 683fdd1..1225751 100644
--- a/dashboardv2/public/css/scss/graph.scss
+++ b/dashboardv2/public/css/scss/graph.scss
@@ -450,33 +450,6 @@ span#zoom_in {
     }
 }
 
-.isIncomplete {
-
-    foreignObject {
-        display: none;
-    }
-
-    &.show {
-        image {
-            opacity: 0.2;
-            animation: blink 2.5s infinite;
-        }
-
-        foreignObject {
-            display: block;
-        }
-    }
-
-    i.fa-refresh {
-
-        text-align: center;
-        margin-top: 33%;
-        font-size: 15px;
-    }
-
-}
-
-
 @-webkit-keyframes blink {
     from {
         opacity: 0.2;
diff --git a/dashboardv2/public/css/scss/table.scss b/dashboardv2/public/css/scss/table.scss
index 358d60a..f14ebfb 100644
--- a/dashboardv2/public/css/scss/table.scss
+++ b/dashboardv2/public/css/scss/table.scss
@@ -168,4 +168,79 @@ tr.empty {
 .toggleList.semi-collapsed div:nth-child(n+2) {
     display: none;
 
+}
+
+.table-quickMenu {
+    border: thin $lightGrey solid;
+    border-collapse: separate;
+    border-radius: 6px;
+    box-shadow: 0px 0px 4px #d8d8d8;
+    overflow: scroll !important;
+    max-height: 500px;
+    width: 100%;
+
+    .resizeHandler {
+        &.grid-draggable {
+            background-color: $color_jungle_green_approx !important;
+        }
+
+        &:hover {
+            border-left: 1px solid #d2d2d2;
+        }
+    }
+
+    >thead>tr>th {
+        border-width: thin;
+        border-color: $color_jungle_green_approx;
+        border-bottom-style: solid;
+        box-shadow: none;
+        padding: 12px 15px !important;
+        background-color: transparent;
+        text-align: left;
+        font-weight: 800;
+        border-top: 0;
+        font-size: 14px;
+        letter-spacing: 0.25px;
+        color: rgba(52, 52, 52, 1);
+    }
+
+    >tbody>tr>td {
+        border-color: $color_gallery_approx;
+        color: #333333;
+        font-weight: 100;
+        padding: 9px 15px;
+    }
+}
+
+td {
+
+    div.scroll-y,
+    pre.scroll-y {
+        max-height: 200px;
+        overflow-y: auto;
+        word-break: break-word;
+    }
+
+    &.searchTableName {
+        &:hover {
+            img {
+                transform: scale(1.5);
+                transform-origin: 100% 50%;
+                transition: transform 0.2s;
+            }
+        }
+
+        a {
+            max-width: calc(100% - 36px);
+            overflow: hidden;
+            float: left;
+            text-overflow: ellipsis;
+        }
+
+        img {
+            height: 20px;
+            margin: 0px 5px;
+            float: left;
+        }
+    }
 }
\ No newline at end of file
diff --git a/dashboardv2/public/css/scss/theme.scss b/dashboardv2/public/css/scss/theme.scss
index c93d7d0..1b24407 100644
--- a/dashboardv2/public/css/scss/theme.scss
+++ b/dashboardv2/public/css/scss/theme.scss
@@ -512,27 +512,77 @@ hr[size="10"] {
     }
 }
 
-.entityDetail {
+td.searchTableName:hover {
     .isIncomplete {
-        &.show {
-            img {
-                opacity: .2;
-                animation: blink 2.5s infinite;
+        &.show.search-result-page {
+            i {
+                left: 7px;
             }
+        }
+    }
+}
+
+.isIncomplete {
+    &.show {
+        img {
+            opacity: .2;
+            //animation: blink 2.5s infinite;
+        }
+
+        i.fa {
+            display: block;
+        }
+
+        .entity-icon-box {
+            background: none;
+
+            i.fa {
+                top: 27px;
+                font-size: 18px;
+            }
+        }
 
-            i.fa.fa-refresh {
-                display: block;
+
+        foreignObject {
+            display: block;
+
+            i.fa {
+                font-size: 15px;
+                top: 17px;
+                left: 18.5px;
             }
         }
 
-        i.fa.fa-refresh {
-            display: none;
-            text-align: center;
-            font-size: 20px;
-            top: 0;
-            position: absolute;
-            z-index: 999;
-            left: calc(50% - 8px);
+        image {
+            opacity: 0.2;
+            //animation: blink 2.5s infinite;
         }
+
+        &.search-result-page {
+            position: relative;
+
+            i {
+                left: 13px;
+                font-size: 9px;
+                top: 5px;
+            }
+
+        }
+
+    }
+
+    foreignObject {
+        display: none;
+    }
+
+    i.fa {
+        color: #898989;
+        display: none;
+        text-align: center;
+        font-size: 16px;
+        top: 0;
+        position: absolute;
+        z-index: 1;
+        left: calc(50% - 8px);
     }
 }
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html b/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html
index dd45cc8..f14abba 100644
--- a/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html
@@ -139,7 +139,7 @@
     </div>
     <div class="legends pull-left" style="height: 25px; padding: 2px;">
         <span style="margin-right: 8px; color:#fb4200;"><i class="fa fa-circle-o fa-fw"></i>Current Entity</span>
-        <span style="margin-right: 8px;"><i class="fa fa-refresh fa-fw"></i>In Progress</span>
+        <span style="margin-right: 8px;"><i class="fa fa-hourglass-half fa-fw"></i>In Progress</span>
         <span style="margin-right: 8px; color:#df9b00;"><i class="fa fa-long-arrow-right fa-fw"></i>Lineage</span>
         <span style="margin-right: 8px; color:#fb4200;"><i class="fa fa-long-arrow-right fa-fw"></i>Impact</span>
     </div>
diff --git a/dashboardv2/public/js/templates/search/AdvancedSearchInfo_tmpl.html b/dashboardv2/public/js/templates/search/AdvancedSearchInfo_tmpl.html
index 7746974..64f1a31 100644
--- a/dashboardv2/public/js/templates/search/AdvancedSearchInfo_tmpl.html
+++ b/dashboardv2/public/js/templates/search/AdvancedSearchInfo_tmpl.html
@@ -31,6 +31,6 @@
         </li>
     </ul>
     <h5 style="padding-left: 22.5px;">
-        <a href="http://atlas.apache.org/Search-Advanced.html" target="_blank"><i class="fa fa-info-circle" aria-hidden="true"></i> &nbsp; More sample queries and use-cases</a>
+        <a href="http://atlas.apache.org/#/SearchAdvance" target="_blank"><i class="fa fa-info-circle" aria-hidden="true"></i> &nbsp; More sample queries and use-cases</a>
     </h5>
 </div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/graph/LineageLayoutView.js b/dashboardv2/public/js/views/graph/LineageLayoutView.js
index f6a8d00..d481251 100644
--- a/dashboardv2/public/js/views/graph/LineageLayoutView.js
+++ b/dashboardv2/public/js/views/graph/LineageLayoutView.js
@@ -639,7 +639,7 @@ define(['require',
                         .attr("height", "50")
                         .append("xhtml:div")
                         .insert("i")
-                        .attr("class", "fa fa-refresh fa-spin-custom");
+                        .attr("class", "fa fa-hourglass-half");
 
                     node.intersect = function(point) {
                         return dagreD3.intersect.circle(node, currentNode ? 24 : 21, point);
@@ -876,7 +876,7 @@ define(['require',
                         } else if (that.filterObj.isDeletedEntityHideCheck && nodeData && nodeData.isDeleted) {
                             return
                         }
-                        typeStr += '<option value="' + obj.guid + '">' + obj.attributes.name + '</option>';
+                        typeStr += '<option value="' + obj.guid + '">' + obj.displayText + '</option>';
                     });
                 }
                 this.ui.lineageTypeSearch.html(typeStr);
@@ -997,6 +997,7 @@ define(['require',
                     }
                     $('.hidden-svg').html(svgClone);
                     $(svgClone).find('>g').attr("transform", "scale(" + scaleFactor + ")");
+                    $(svgClone).find("foreignObject").remove();
                     var canvasOffset = { x: 150, y: 150 },
                         setWidth = (svgClone.getBBox().width + (canvasOffset.x)),
                         setHeight = (svgClone.getBBox().height + (canvasOffset.y)),
diff --git a/dashboardv2/public/js/views/search/SearchResultLayoutView.js b/dashboardv2/public/js/views/search/SearchResultLayoutView.js
index 021869b..e997d6b 100644
--- a/dashboardv2/public/js/views/search/SearchResultLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchResultLayoutView.js
@@ -678,7 +678,35 @@ define(['require',
                                 nameHtml += '<button type="button" title="Deleted" class="btn btn-action btn-md deleteBtn"><i class="fa fa-trash"></i></button>';
                                 nameHtml = '<div class="readOnly readOnlyLink">' + nameHtml + '</div>';
                             }
-                            return nameHtml;
+                            var getImageData = function(options) {
+                                var imagePath = options.imagePath,
+                                    returnImgUrl = null;
+                                $.ajax({
+                                        "url": imagePath,
+                                        "method": "get",
+                                        "async": false,
+                                    })
+                                    .always(function(data, status, xhr) {
+                                        if (data.status == 404) {
+                                            returnImgUrl = getImageData({
+                                                "imagePath": Utils.getEntityIconPath({ entityData: obj, errorUrl: imagePath })
+                                            });
+                                        } else if (data) {
+                                            returnImgUrl = imagePath;
+                                        }
+                                    });
+                                return returnImgUrl;
+                            }
+                            var imgPath = getImageData({ imagePath: Utils.getEntityIconPath({ entityData: obj }) }),
+                                img = "",
+                                isIncompleteClass = "isIncomplete search-result-page";
+                            if (obj.isIncomplete === true) {
+                                isIncompleteClass += " show";
+                            }
+                            if (imgPath) {
+                                img = "<div class='" + isIncompleteClass + "'><img src='" + imgPath + "'><i class='fa fa-hourglass-half'></i></div>";
+                            }
+                            return (img + nameHtml);
                         }
                     })
                 };
diff --git a/dashboardv3/public/css/scss/graph.scss b/dashboardv3/public/css/scss/graph.scss
index 5d3c308..101024c 100644
--- a/dashboardv3/public/css/scss/graph.scss
+++ b/dashboardv3/public/css/scss/graph.scss
@@ -443,33 +443,6 @@ span#zoom_in {
     }
 }
 
-.isIncomplete {
-
-    foreignObject {
-        display: none;
-    }
-
-    &.show {
-        image {
-            opacity: 0.2;
-            animation: blink 2.5s infinite;
-        }
-
-        foreignObject {
-            display: block;
-        }
-    }
-
-    i.fa-refresh {
-
-        text-align: center;
-        margin-top: 33%;
-        font-size: 15px;
-    }
-
-}
-
-
 @-webkit-keyframes blink {
     from {
         opacity: 0.2;
diff --git a/dashboardv3/public/css/scss/theme.scss b/dashboardv3/public/css/scss/theme.scss
index c4f84d0..34df2c3 100644
--- a/dashboardv3/public/css/scss/theme.scss
+++ b/dashboardv3/public/css/scss/theme.scss
@@ -692,27 +692,78 @@ hr[size="10"] {
     border-bottom-color: #000;
 }
 
-.entityDetail {
+
+td.searchTableName:hover {
     .isIncomplete {
-        &.show {
-            img {
-                opacity: .2;
-                animation: blink 2.5s infinite;
+        &.show.search-result-page {
+            i {
+                left: 7px;
+            }
+        }
+    }
+}
+
+.isIncomplete {
+    &.show {
+        img {
+            opacity: .2;
+            //animation: blink 2.5s infinite;
+        }
+
+        i.fa {
+            display: block;
+        }
+
+        .entity-icon-box {
+            background: none;
+
+            i.fa {
+                top: 27px;
+                font-size: 18px;
             }
+        }
 
-            i.fa.fa-refresh {
-                display: block;
+
+        foreignObject {
+            display: block;
+
+            i.fa {
+                font-size: 15px;
+                top: 17px;
+                left: 18.5px;
             }
         }
 
-        i.fa.fa-refresh {
-            display: none;
-            text-align: center;
-            font-size: 20px;
-            top: 0;
-            position: absolute;
-            z-index: 1;
-            left: calc(50% - 8px);
+        image {
+            opacity: 0.2;
+            //animation: blink 2.5s infinite;
+        }
+
+        &.search-result-page {
+            position: relative;
+
+            i {
+                left: 13px;
+                font-size: 9px;
+                top: 5px;
+            }
+
         }
+
+    }
+
+    foreignObject {
+        display: none;
+    }
+
+    i.fa {
+        color: #898989;
+        display: none;
+        text-align: center;
+        font-size: 16px;
+        top: 0;
+        position: absolute;
+        z-index: 1;
+        left: calc(50% - 8px);
     }
 }
\ No newline at end of file
diff --git a/dashboardv3/public/js/templates/graph/LineageLayoutView_tmpl.html b/dashboardv3/public/js/templates/graph/LineageLayoutView_tmpl.html
index dd45cc8..f14abba 100644
--- a/dashboardv3/public/js/templates/graph/LineageLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/graph/LineageLayoutView_tmpl.html
@@ -139,7 +139,7 @@
     </div>
     <div class="legends pull-left" style="height: 25px; padding: 2px;">
         <span style="margin-right: 8px; color:#fb4200;"><i class="fa fa-circle-o fa-fw"></i>Current Entity</span>
-        <span style="margin-right: 8px;"><i class="fa fa-refresh fa-fw"></i>In Progress</span>
+        <span style="margin-right: 8px;"><i class="fa fa-hourglass-half fa-fw"></i>In Progress</span>
         <span style="margin-right: 8px; color:#df9b00;"><i class="fa fa-long-arrow-right fa-fw"></i>Lineage</span>
         <span style="margin-right: 8px; color:#fb4200;"><i class="fa fa-long-arrow-right fa-fw"></i>Impact</span>
     </div>
diff --git a/dashboardv3/public/js/views/graph/LineageLayoutView.js b/dashboardv3/public/js/views/graph/LineageLayoutView.js
index 2dbe01f..a15047c 100644
--- a/dashboardv3/public/js/views/graph/LineageLayoutView.js
+++ b/dashboardv3/public/js/views/graph/LineageLayoutView.js
@@ -654,7 +654,7 @@ define(['require',
                         .attr("height", "50")
                         .append("xhtml:div")
                         .insert("i")
-                        .attr("class", "fa fa-refresh fa-spin-custom");
+                        .attr("class", "fa fa-hourglass-half");
 
                     node.intersect = function(point) {
                         return dagreD3.intersect.circle(node, currentNode ? 24 : 21, point);
@@ -891,7 +891,7 @@ define(['require',
                         } else if (that.filterObj.isDeletedEntityHideCheck && nodeData && nodeData.isDeleted) {
                             return
                         }
-                        typeStr += '<option value="' + obj.guid + '">' + obj.attributes.name + '</option>';
+                        typeStr += '<option value="' + obj.guid + '">' + obj.displayText + '</option>';
                     });
                 }
                 this.ui.lineageTypeSearch.html(typeStr);
@@ -1012,6 +1012,7 @@ define(['require',
                     }
                     $('.hidden-svg').html(svgClone);
                     $(svgClone).find('>g').attr("transform", "scale(" + scaleFactor + ")");
+                    $(svgClone).find("foreignObject").remove();
                     var canvasOffset = { x: 150, y: 150 },
                         setWidth = (svgClone.getBBox().width + (canvasOffset.x)),
                         setHeight = (svgClone.getBBox().height + (canvasOffset.y)),
diff --git a/dashboardv3/public/js/views/search/SearchResultLayoutView.js b/dashboardv3/public/js/views/search/SearchResultLayoutView.js
index dbd368b..b4e2290 100644
--- a/dashboardv3/public/js/views/search/SearchResultLayoutView.js
+++ b/dashboardv3/public/js/views/search/SearchResultLayoutView.js
@@ -710,9 +710,13 @@ define(['require',
                                 return returnImgUrl;
                             }
                             var imgPath = getImageData({ imagePath: Utils.getEntityIconPath({ entityData: obj }) }),
-                                img = ""
+                                img = "",
+                                isIncompleteClass = "isIncomplete search-result-page";
+                            if (obj.isIncomplete === true) {
+                                isIncompleteClass += " show";
+                            }
                             if (imgPath) {
-                                img = "<img src='" + imgPath + "'>";
+                                img = "<div class='" + isIncompleteClass + "'><img src='" + imgPath + "'><i class='fa fa-hourglass-half'></i></div>";
                             }
                             return (img + nameHtml);
                         }


[atlas] 01/02: ATLAS:3456 : Allows user to add label in entity detail page.

Posted by sa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sarath pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/atlas.git

commit 4ba0a335f82bed67c7e086c1e21f40cd45f8d396
Author: sameer79 <fi...@yahoo.co.in>
AuthorDate: Thu Oct 10 11:25:04 2019 -0700

    ATLAS:3456 : Allows user to add label in entity detail page.
    
    (cherry picked from commit 715845523fed2e96bdbeba31a8f68db1d80c79f1)
---
 dashboardv2/public/css/scss/common.scss            |  13 ++-
 dashboardv2/public/css/scss/panel.scss             |  16 +--
 dashboardv2/public/js/models/VEntity.js            |  10 +-
 .../detail_page/DetailPageLayoutView_tmpl.html     |   1 +
 .../entity/EntityLabelDefineView_tmpl.html         |  97 +++++++++++++++++
 .../public/js/templates/site/Statistics_tmpl.html  |  10 +-
 dashboardv2/public/js/utils/UrlLinks.js            |   5 +-
 .../js/views/detail_page/DetailPageLayoutView.js   |  12 ++-
 .../js/views/entity/EntityDetailTableLayoutView.js |   2 +-
 .../js/views/entity/EntityLabelDefineView.js       | 120 +++++++++++++++++++++
 .../public/js/views/entity/EntityUserDefineView.js |   2 +-
 dashboardv3/public/css/scss/common.scss            |  13 ++-
 dashboardv3/public/css/scss/panel.scss             |  16 +--
 dashboardv3/public/js/models/VEntity.js            |  10 +-
 .../detail_page/DetailPageLayoutView_tmpl.html     |   1 +
 .../entity/EntityLabelDefineView_tmpl.html         |  97 +++++++++++++++++
 .../public/js/templates/site/Statistics_tmpl.html  |  10 +-
 dashboardv3/public/js/utils/UrlLinks.js            |   5 +-
 .../js/views/detail_page/DetailPageLayoutView.js   |  10 +-
 .../js/views/entity/EntityDetailTableLayoutView.js |   2 +-
 .../js/views/entity/EntityLabelDefineView.js       | 120 +++++++++++++++++++++
 .../public/js/views/entity/EntityUserDefineView.js |   2 +-
 22 files changed, 533 insertions(+), 41 deletions(-)

diff --git a/dashboardv2/public/css/scss/common.scss b/dashboardv2/public/css/scss/common.scss
index b24c3c3..6fbef88 100644
--- a/dashboardv2/public/css/scss/common.scss
+++ b/dashboardv2/public/css/scss/common.scss
@@ -228,16 +228,18 @@ pre {
         .custom-col-0{
             text-align: center;
             vertical-align: middle;
+            line-height: 31px;
             width: 2%;
         }
 
         .custom-col-1{
-            width: 43%;
+            width: 40%;
         }
 
         .custom-col-2{
             text-align: center;
-            width: 10%;
+            width: 12%;
+            margin-left: 2%;
         }
     }
 }
@@ -245,3 +247,10 @@ pre {
 .errorMsg {
     color: $red;
 }
+
+.badge-default {
+    background-color: $color_havelock_blue_approx;
+    color: $white;
+    font-size: 12px;
+    font-weight: normal;
+}
diff --git a/dashboardv2/public/css/scss/panel.scss b/dashboardv2/public/css/scss/panel.scss
index e6dd4bb..9a97835 100644
--- a/dashboardv2/public/css/scss/panel.scss
+++ b/dashboardv2/public/css/scss/panel.scss
@@ -31,7 +31,7 @@
 
         .panel-title {
             font-weight: bold;
-            padding-top: 8px;
+            padding-top: 6px;
         }
     }
 
@@ -102,26 +102,26 @@
         }
 
         i.ec-icon:before {
-            content: "\f078"
+            content: "\f054"
         }
 
         &.collapsed,
         &[aria-expanded="false"] {
             i.ec-icon:before {
-                content: "\f078"
+                content: "\f054"
             }
         }
 
         &[aria-expanded="true"] {
             i.ec-icon:before {
-                content: "\f077"
+                content: "\f078"
             }
         }
     }
 }
 
 .panel-default.custom-panel>.panel-heading {
-    color: $black;
+    color: $color_jungle_green_approx;
     cursor: pointer;
     border-bottom: none;
     display: inline-block;
@@ -129,12 +129,12 @@
     .panel-title {
         font-weight: normal;
         a:hover {
-            color: $black;
+            color: $color_jungle_green_approx;
             opacity: 0.7;
         }
     }
     .btn-group {
-        margin-top: 3px;
+        margin-top: 4px;
     }
 }
 
@@ -151,5 +151,5 @@
     border-top: none;
 }
 .panel-default.custom-panel>.panel-heading > .btn-group > button {
-    color: $black;
+    color: $color_jungle_green_approx;
 }
diff --git a/dashboardv2/public/js/models/VEntity.js b/dashboardv2/public/js/models/VEntity.js
index deeb6b0..984039d 100644
--- a/dashboardv2/public/js/models/VEntity.js
+++ b/dashboardv2/public/js/models/VEntity.js
@@ -87,7 +87,15 @@ define(['require',
                 dataType: 'json'
             }, options);
             return this.constructor.nonCrudOperation.call(this, url, "", options);
+        },
+        saveEntityLabels: function(guid, options) {
+            var url = UrlLinks.entityLabelsAPIUrl(guid);
+            options = _.extend({
+                contentType: 'application/json',
+                dataType: 'json'
+            }, options);
+            return this.constructor.nonCrudOperation.call(this, url, "POST", options);
         }
     }, {});
     return VEntity;
-});
\ No newline at end of file
+});
diff --git a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
index c6f88c6..cbd222c 100644
--- a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
@@ -75,6 +75,7 @@
                 </div>
                 <div class="col-md-6">
                     <div id="r_entityUserDefineView"></div>
+                    <div id="r_entityLabelDefineView"></div>
                 </div>
             </div>
         </div>
diff --git a/dashboardv2/public/js/templates/entity/EntityLabelDefineView_tmpl.html b/dashboardv2/public/js/templates/entity/EntityLabelDefineView_tmpl.html
new file mode 100644
index 0000000..06d7e0e
--- /dev/null
+++ b/dashboardv2/public/js/templates/entity/EntityLabelDefineView_tmpl.html
@@ -0,0 +1,97 @@
+<!--
+ * 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="panel-group" id="accordion">
+
+    <div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="userDefineLabel">
+        {{#ifCond labels.length "===" 0}}
+            <div class="panel-heading collapsed" data-toggle="collapse" href="#collapse3" aria-expanded="false" style="width: 70%">
+                <h4 class="panel-title">
+                    <a>Labels </a>
+                </h4>
+                <div class="btn-group pull-left">
+                    <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
+                </div>
+            </div>
+        {{else}}
+            <div class="panel-heading" data-toggle="collapse" href="#collapse3" aria-expanded="true" style="width: 70%">
+                <h4 class="panel-title">
+                    <a>Labels </a>
+                </h4>
+                <div class="btn-group pull-left">
+                    <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
+                </div>
+            </div>
+
+        {{/ifCond}}
+
+        {{#ifCond readOnlyEntity "===" false}}
+            <div class="panel-actions">
+                    {{#ifCond  swapItem "!==" true}}
+                        <button class="btn btn-action btn-sm"  data-id="addLabels" {{#ifCond labels.length "===" 0}} data-original-title="Add User-Defined Labels" {{else}} data-original-title="Edit User-Defined Labels"  {{/ifCond}}>
+                            {{#ifCond labels.length "===" 0}} Add {{else}} Edit {{/ifCond}}
+                        </button>
+                    {{/ifCond}}
+                    {{#ifCond saveLabels "===" true}}
+                        <button class="btn btn-action btn-sm"  data-id="saveLabels"  data-original-title="Save User-Defined Labels">Save</button>
+                    {{/ifCond}}
+            </div>
+        {{/ifCond}}
+
+        <div id="collapse3" {{#ifCond swapItem "===" false}} class="panel-collapse collapse" {{else}} class="panel-collapse collapse in" {{/ifCond}}>
+            {{#ifCond labels.length "===" 0}}
+                <div class="panel-body">
+                        <div class="row">
+                            <div class="col-md-12">
+                                {{#ifCond swapItem "===" true}}
+                                    <select class="form-control" data-id="addLabelOptions" multiple="multiple"></select>
+                                {{else}}
+                                <div class="badge-container">
+                                        {{#each labels}}
+                                            <label class="label badge-default">{{this}}</label>
+                                        {{/each}}
+                                </div>
+                                {{/ifCond}}
+                            </div>
+                        </div>
+                </div>
+            {{/ifCond}}
+        </div>
+
+        {{#ifCond labels.length ">" 0}}
+            <div id="collapse3" class="panel-collapse collapse in" >
+                <div class="panel-body">
+                        <div class="row">
+                            <div class="col-md-12">
+                                {{#ifCond swapItem "===" true}}
+                                    <select class="form-control" data-id="addLabelOptions" multiple="multiple"></select>
+                                {{else}}
+                                <div class="badge-container">
+                                        {{#each labels}}
+                                            <label class="label badge-default">{{this}}</label>
+                                        {{/each}}
+                                </div>
+                                {{/ifCond}}
+                            </div>
+                        </div>
+                </div>
+            </div>
+        {{/ifCond}}
+
+
+    </div>
+</div>
diff --git a/dashboardv2/public/js/templates/site/Statistics_tmpl.html b/dashboardv2/public/js/templates/site/Statistics_tmpl.html
index 436767c..f5c6c8b 100644
--- a/dashboardv2/public/js/templates/site/Statistics_tmpl.html
+++ b/dashboardv2/public/js/templates/site/Statistics_tmpl.html
@@ -15,12 +15,12 @@
  * limitations under the License.
 -->
 <div class="panel-group server-stats-container statsContainer hide" id="accordion">
-    <div class="panel panel-default expand_collapse_panel-icon" data-id="entity">
+    <div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="entity">
         <div class="panel-heading" data-toggle="collapse" href="#collapse1" aria-expanded="true">
             <h4 class="panel-title">
                 <a>Entities <span class="count">(0)</span></a>
             </h4>
-            <div class="btn-group pull-right">
+            <div class="btn-group pull-left">
                 <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
             </div>
         </div>
@@ -36,12 +36,12 @@
             </div>
         </div>
     </div>
-    <div class="panel panel-default expand_collapse_panel-icon" data-id="stats">
+    <div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="stats">
         <div class="panel-heading" data-toggle="collapse" href="#collapse3" aria-expanded="true">
             <h4 class="panel-title">
                 <a>Server Statistics </a>
             </h4>
-            <div class="btn-group pull-right">
+            <div class="btn-group pull-left">
                 <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
             </div>
         </div>
@@ -90,4 +90,4 @@
 </div>
 <div class="fontLoader-relative statsLoader show">
     <i class="fa fa-refresh fa-spin-custom"></i>
-</div>
\ No newline at end of file
+</div>
diff --git a/dashboardv2/public/js/utils/UrlLinks.js b/dashboardv2/public/js/utils/UrlLinks.js
index f6e1795..dbb1a0a 100644
--- a/dashboardv2/public/js/utils/UrlLinks.js
+++ b/dashboardv2/public/js/utils/UrlLinks.js
@@ -78,6 +78,9 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
                 return entitiesUrl += '?minExtInfo=' + (minExtInfo);
             }
         },
+        entityLabelsAPIUrl: function(guid) {
+            return this.entitiesApiUrl({ guid: guid }) + "/labels";
+        },
         entityHeaderApiUrl: function(guid) {
             return this.entitiesApiUrl({ guid: guid }) + "/header"
         },
@@ -221,4 +224,4 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
     });
 
     return UrlLinks;
-});
\ 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 ffd36ac..771fac3 100644
--- a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
+++ b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
@@ -47,6 +47,7 @@ define(['require',
                 RProfileLayoutView: "#r_profileLayoutView",
                 RRelationshipLayoutView: "#r_relationshipLayoutView",
                 REntityUserDefineView: "#r_entityUserDefineView",
+                REntityLabelDefineView: "#r_entityLabelDefineView"
             },
             /** ui selector cache */
             ui: {
@@ -196,7 +197,7 @@ define(['require',
                                 if (collectionJSON.isIncomplete === true) {
                                     this.$(".isIncomplete").addClass("show");
                                 }
-                                this.ui.entityIcon.attr('title', _.escape(collectionJSON.typeName)).html('<img src="' + Utils.getEntityIconPath({ entityData: entityData }) + '"/><i class="fa fa-refresh fa-spin-custom"></i>').find("img").on('error', function() {
+                                this.ui.entityIcon.attr('title', _.escape(collectionJSON.typeName)).html('<img src="' + Utils.getEntityIconPath({ entityData: entityData }) + '"/><i class="fa fa-hourglass-half"></i>').find("img").on('error', function() {
                                     this.src = Utils.getEntityIconPath({ entityData: entityData, errorUrl: this.src });
                                 });
                             } else {
@@ -248,6 +249,7 @@ define(['require',
                     }
                     this.renderEntityDetailTableLayoutView(obj);
                     this.renderEntityUserDefineView(obj);
+                    this.renderEntityLabelDefineView(obj);
                     this.renderRelationshipLayoutView(obj);
                     this.renderAuditTableLayoutView(obj);
                     this.renderTagTableLayoutView(obj);
@@ -425,7 +427,7 @@ define(['require',
                 _.each(data, function(val) {
                     // if (val.relationshipStatus == "ACTIVE") {
                     termData += '<span class="btn btn-action btn-sm btn-icon btn-blue" data-id="termClick"><span title=' + _.escape(val.displayText) + '>' + _.escape(val.displayText) + '</span><i class="' + (val.relationshipStatus == "ACTIVE" ? 'fa fa-close' : "") + '" data-id="deleteTerm" data-guid="' + val.guid + '" data-type="term" title="Remove Term"></i></span>';
-                    // } 
+                    // }
                 });
                 this.ui.termList.find("span.btn").remove();
                 this.ui.termList.prepend(termData);
@@ -495,6 +497,12 @@ define(['require',
                     that.REntityUserDefineView.show(new EntityUserDefineView(obj));
                 });
             },
+            renderEntityLabelDefineView: function(obj) {
+                var that = this;
+                require(['views/entity/EntityLabelDefineView'], function(EntityLabelDefineView) {
+                    that.REntityLabelDefineView.show(new EntityLabelDefineView(obj));
+                });
+            },
             renderTagTableLayoutView: function(obj) {
                 var that = this;
                 require(['views/tag/TagDetailTableLayoutView'], function(TagDetailTableLayoutView) {
diff --git a/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js b/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js
index 6572292..381d99e 100644
--- a/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js
+++ b/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js
@@ -83,4 +83,4 @@ define(['require',
             }
         });
     return EntityDetailTableLayoutView;
-});
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/entity/EntityLabelDefineView.js b/dashboardv2/public/js/views/entity/EntityLabelDefineView.js
new file mode 100644
index 0000000..d69b277
--- /dev/null
+++ b/dashboardv2/public/js/views/entity/EntityLabelDefineView.js
@@ -0,0 +1,120 @@
+/**
+ * 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.
+ */
+
+define(['require',
+'backbone',
+'hbs!tmpl/entity/EntityLabelDefineView_tmpl',
+'models/VEntity',
+'utils/Utils',
+'utils/Messages',
+'utils/Enums'
+], function(require, Backbone, EntityLabelDefineView_tmpl, VEntity, Utils, Messages, Enums) {
+'use strict';
+
+    return Backbone.Marionette.LayoutView.extend({
+        _viewName: 'REntityLabelDefineView',
+        template: EntityLabelDefineView_tmpl,
+        templateHelpers: function() {
+            return {
+                swapItem: this.swapItem,
+                labels: this.labels,
+                saveLabels: this.saveLabels,
+                readOnlyEntity: this.readOnlyEntity
+            };
+        },
+        ui: {
+            addLabelOptions: "[data-id='addLabelOptions']",
+            addLabels: "[data-id='addLabels']",
+            saveLabels: "[data-id='saveLabels']"
+        },
+        events: function() {
+            var events = {};
+            events["change " + this.ui.addLabelOptions] = 'onChangeLabelChange';
+            events["click " + this.ui.addLabels] = 'handleBtnClick';
+            events["click " + this.ui.saveLabels] = 'saveUserDefinedLabels';
+            return events;
+        },
+        initialize: function(options) {
+            var self = this;
+            _.extend(this, _.pick(options, 'entity'));
+            this.swapItem = false, this.saveLabels = false;
+            this.readOnlyEntity = Enums.entityStateReadOnly[this.entity.status]
+            this.entityModel = new VEntity(this.entity);
+            this.labels = this.entity.labels || [];
+        },
+        onRender: function() {
+            this.populateLabelOptions();
+        },
+        bindEvents: function () {
+        },
+        populateLabelOptions: function() {
+            var that = this,
+            str = this.labels.map(function (label) {
+                return "<option selected > "+ label +" </option>";
+            });
+            this.ui.addLabelOptions.html(str);
+            this.ui.addLabelOptions.select2({
+                placeholder: "Select Label",
+                allowClear: true,
+                tags: true,
+                multiple: true
+            });
+        },
+        onChangeLabelChange: function () {
+            this.labels = this.ui.addLabelOptions.val();
+        },
+        handleBtnClick: function () {
+            this.swapItem = !this.swapItem;
+            this.saveLabels = this.swapItem === true ? true : false;
+            this.render();
+        },
+        saveUserDefinedLabels: function() {
+            var that = this;
+            var entityJson = that.entityModel.toJSON();
+            var payload = this.labels;
+            that.entityModel.saveEntityLabels(entityJson.guid ,{
+                data: JSON.stringify(payload),
+                type: 'POST',
+                success: function() {
+                    var msg = entityJson.labels === undefined ? 'addSuccessMessage' : 'editSuccessMessage';
+                    if (payload.length === 0) {
+                        that.entityModel.unset('labels');
+                    } else {
+                        that.entityModel.set('labels', payload);
+                    }
+                    Utils.notifySuccess({
+                        content: "User-defined labels " + Messages[msg]
+                    });
+                    that.swapItem = false;
+                    that.saveLabels = false;
+                    that.render();
+                },
+                error: function (e) {
+                    that.ui.saveLabels && that.ui.saveLabels.length > 0 &&  that.ui.saveLabels[0].setAttribute("disabled", false);
+                    Utils.notifySuccess({
+                        content: e.message
+                    });
+                },
+                complete: function () {
+                    that.ui.saveLabels && that.ui.saveLabels.length > 0 && that.ui.saveLabels[0].setAttribute("disabled", false);
+                    that.render();
+                }
+            });
+        }
+    });
+});
diff --git a/dashboardv2/public/js/views/entity/EntityUserDefineView.js b/dashboardv2/public/js/views/entity/EntityUserDefineView.js
index 588703f..a23a8fa 100644
--- a/dashboardv2/public/js/views/entity/EntityUserDefineView.js
+++ b/dashboardv2/public/js/views/entity/EntityUserDefineView.js
@@ -81,7 +81,7 @@ define(['require',
                 okText: 'Save',
                 okCloses: false,
                 cancelText: "Cancel",
-                mainClass: 'modal-lg',
+                mainClass: 'modal-md',
                 allowCancel: true,
             };
            this.setAttributeModal(modalObj);
diff --git a/dashboardv3/public/css/scss/common.scss b/dashboardv3/public/css/scss/common.scss
index dfe0e4f..24231d1 100644
--- a/dashboardv3/public/css/scss/common.scss
+++ b/dashboardv3/public/css/scss/common.scss
@@ -227,16 +227,18 @@ pre {
         .custom-col-0{
             text-align: center;
             vertical-align: middle;
+            line-height: 31px;
             width: 2%;
         }
 
         .custom-col-1{
-            width: 43%;
+            width: 40%;
         }
 
         .custom-col-2{
             text-align: center;
-            width: 10%;
+            width: 12%;
+            margin-left: 2%;
         }
     }
 }
@@ -244,3 +246,10 @@ pre {
 .errorMsg {
     color: $red;
 }
+
+.badge-default {
+    background-color: $color_havelock_blue_approx;
+    color: $white;
+    font-size: 12px;
+    font-weight: normal;
+}
diff --git a/dashboardv3/public/css/scss/panel.scss b/dashboardv3/public/css/scss/panel.scss
index 931a9a6..6635eb7 100644
--- a/dashboardv3/public/css/scss/panel.scss
+++ b/dashboardv3/public/css/scss/panel.scss
@@ -37,7 +37,7 @@
 
         .panel-title {
             font-weight: bold;
-            padding-top: 8px;
+            padding-top: 6px;
         }
     }
 
@@ -117,19 +117,19 @@
             }
 
             i.ec-icon:before {
-                content: "\f078"
+                content: "\f054"
             }
 
             &.collapsed,
             &[aria-expanded="false"] {
                 i.ec-icon:before {
-                    content: "\f078"
+                    content: "\f054"
                 }
             }
 
             &[aria-expanded="true"] {
                 i.ec-icon:before {
-                    content: "\f077"
+                    content: "\f078"
                 }
             }
         }
@@ -137,7 +137,7 @@
 }
 
 .panel-default.custom-panel>.panel-heading {
-    color: $black;
+    color: $color_jungle_green_approx;
     cursor: pointer;
     border-bottom: none;
     display: inline-block;
@@ -145,12 +145,12 @@
     .panel-title {
         font-weight: normal;
         a:hover {
-            color: $black;
+            color: $color_jungle_green_approx;
             opacity: 0.7;
         }
     }
     .btn-group {
-        margin-top: 3px;
+        margin-top: 4px;
     }
 }
 
@@ -167,5 +167,5 @@
     border-top: none;
 }
 .panel-default.custom-panel>.panel-heading > .btn-group > button {
-    color: $black;
+    color: $color_jungle_green_approx;
 }
diff --git a/dashboardv3/public/js/models/VEntity.js b/dashboardv3/public/js/models/VEntity.js
index deeb6b0..984039d 100644
--- a/dashboardv3/public/js/models/VEntity.js
+++ b/dashboardv3/public/js/models/VEntity.js
@@ -87,7 +87,15 @@ define(['require',
                 dataType: 'json'
             }, options);
             return this.constructor.nonCrudOperation.call(this, url, "", options);
+        },
+        saveEntityLabels: function(guid, options) {
+            var url = UrlLinks.entityLabelsAPIUrl(guid);
+            options = _.extend({
+                contentType: 'application/json',
+                dataType: 'json'
+            }, options);
+            return this.constructor.nonCrudOperation.call(this, url, "POST", options);
         }
     }, {});
     return VEntity;
-});
\ No newline at end of file
+});
diff --git a/dashboardv3/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html b/dashboardv3/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
index f2e6ca7..25f04d9 100644
--- a/dashboardv3/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
@@ -78,6 +78,7 @@
                 </div>
                 <div class="col-md-6">
                     <div id="r_entityUserDefineView"></div>
+                    <div id="r_entityLabelDefineView"></div>
                 </div>
             </div>
         </div>
diff --git a/dashboardv3/public/js/templates/entity/EntityLabelDefineView_tmpl.html b/dashboardv3/public/js/templates/entity/EntityLabelDefineView_tmpl.html
new file mode 100644
index 0000000..06d7e0e
--- /dev/null
+++ b/dashboardv3/public/js/templates/entity/EntityLabelDefineView_tmpl.html
@@ -0,0 +1,97 @@
+<!--
+ * 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="panel-group" id="accordion">
+
+    <div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="userDefineLabel">
+        {{#ifCond labels.length "===" 0}}
+            <div class="panel-heading collapsed" data-toggle="collapse" href="#collapse3" aria-expanded="false" style="width: 70%">
+                <h4 class="panel-title">
+                    <a>Labels </a>
+                </h4>
+                <div class="btn-group pull-left">
+                    <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
+                </div>
+            </div>
+        {{else}}
+            <div class="panel-heading" data-toggle="collapse" href="#collapse3" aria-expanded="true" style="width: 70%">
+                <h4 class="panel-title">
+                    <a>Labels </a>
+                </h4>
+                <div class="btn-group pull-left">
+                    <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
+                </div>
+            </div>
+
+        {{/ifCond}}
+
+        {{#ifCond readOnlyEntity "===" false}}
+            <div class="panel-actions">
+                    {{#ifCond  swapItem "!==" true}}
+                        <button class="btn btn-action btn-sm"  data-id="addLabels" {{#ifCond labels.length "===" 0}} data-original-title="Add User-Defined Labels" {{else}} data-original-title="Edit User-Defined Labels"  {{/ifCond}}>
+                            {{#ifCond labels.length "===" 0}} Add {{else}} Edit {{/ifCond}}
+                        </button>
+                    {{/ifCond}}
+                    {{#ifCond saveLabels "===" true}}
+                        <button class="btn btn-action btn-sm"  data-id="saveLabels"  data-original-title="Save User-Defined Labels">Save</button>
+                    {{/ifCond}}
+            </div>
+        {{/ifCond}}
+
+        <div id="collapse3" {{#ifCond swapItem "===" false}} class="panel-collapse collapse" {{else}} class="panel-collapse collapse in" {{/ifCond}}>
+            {{#ifCond labels.length "===" 0}}
+                <div class="panel-body">
+                        <div class="row">
+                            <div class="col-md-12">
+                                {{#ifCond swapItem "===" true}}
+                                    <select class="form-control" data-id="addLabelOptions" multiple="multiple"></select>
+                                {{else}}
+                                <div class="badge-container">
+                                        {{#each labels}}
+                                            <label class="label badge-default">{{this}}</label>
+                                        {{/each}}
+                                </div>
+                                {{/ifCond}}
+                            </div>
+                        </div>
+                </div>
+            {{/ifCond}}
+        </div>
+
+        {{#ifCond labels.length ">" 0}}
+            <div id="collapse3" class="panel-collapse collapse in" >
+                <div class="panel-body">
+                        <div class="row">
+                            <div class="col-md-12">
+                                {{#ifCond swapItem "===" true}}
+                                    <select class="form-control" data-id="addLabelOptions" multiple="multiple"></select>
+                                {{else}}
+                                <div class="badge-container">
+                                        {{#each labels}}
+                                            <label class="label badge-default">{{this}}</label>
+                                        {{/each}}
+                                </div>
+                                {{/ifCond}}
+                            </div>
+                        </div>
+                </div>
+            </div>
+        {{/ifCond}}
+
+
+    </div>
+</div>
diff --git a/dashboardv3/public/js/templates/site/Statistics_tmpl.html b/dashboardv3/public/js/templates/site/Statistics_tmpl.html
index 436767c..f5c6c8b 100644
--- a/dashboardv3/public/js/templates/site/Statistics_tmpl.html
+++ b/dashboardv3/public/js/templates/site/Statistics_tmpl.html
@@ -15,12 +15,12 @@
  * limitations under the License.
 -->
 <div class="panel-group server-stats-container statsContainer hide" id="accordion">
-    <div class="panel panel-default expand_collapse_panel-icon" data-id="entity">
+    <div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="entity">
         <div class="panel-heading" data-toggle="collapse" href="#collapse1" aria-expanded="true">
             <h4 class="panel-title">
                 <a>Entities <span class="count">(0)</span></a>
             </h4>
-            <div class="btn-group pull-right">
+            <div class="btn-group pull-left">
                 <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
             </div>
         </div>
@@ -36,12 +36,12 @@
             </div>
         </div>
     </div>
-    <div class="panel panel-default expand_collapse_panel-icon" data-id="stats">
+    <div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="stats">
         <div class="panel-heading" data-toggle="collapse" href="#collapse3" aria-expanded="true">
             <h4 class="panel-title">
                 <a>Server Statistics </a>
             </h4>
-            <div class="btn-group pull-right">
+            <div class="btn-group pull-left">
                 <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
             </div>
         </div>
@@ -90,4 +90,4 @@
 </div>
 <div class="fontLoader-relative statsLoader show">
     <i class="fa fa-refresh fa-spin-custom"></i>
-</div>
\ No newline at end of file
+</div>
diff --git a/dashboardv3/public/js/utils/UrlLinks.js b/dashboardv3/public/js/utils/UrlLinks.js
index d619c52..c58c58f 100644
--- a/dashboardv3/public/js/utils/UrlLinks.js
+++ b/dashboardv3/public/js/utils/UrlLinks.js
@@ -79,6 +79,9 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
                 return entitiesUrl += '?minExtInfo=' + (minExtInfo);
             }
         },
+        entityLabelsAPIUrl: function(guid) {
+            return this.entitiesApiUrl({ guid: guid }) + "/labels";
+        },
         entityHeaderApiUrl: function(guid) {
             return this.entitiesApiUrl({ guid: guid }) + "/header"
         },
@@ -222,4 +225,4 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
     });
 
     return UrlLinks;
-});
\ No newline at end of file
+});
diff --git a/dashboardv3/public/js/views/detail_page/DetailPageLayoutView.js b/dashboardv3/public/js/views/detail_page/DetailPageLayoutView.js
index 31671ac..18031ec 100644
--- a/dashboardv3/public/js/views/detail_page/DetailPageLayoutView.js
+++ b/dashboardv3/public/js/views/detail_page/DetailPageLayoutView.js
@@ -47,6 +47,7 @@ define(['require',
                 RProfileLayoutView: "#r_profileLayoutView",
                 RRelationshipLayoutView: "#r_relationshipLayoutView",
                 REntityUserDefineView: "#r_entityUserDefineView",
+                REntityLabelDefineView: "#r_entityLabelDefineView"
             },
             /** ui selector cache */
             ui: {
@@ -201,7 +202,7 @@ define(['require',
                                 if (collectionJSON.isIncomplete === true) {
                                     this.$(".isIncomplete").addClass("show");
                                 }
-                                this.ui.entityIcon.attr('title', _.escape(collectionJSON.typeName)).html('<img src="' + Utils.getEntityIconPath({ entityData: entityData }) + '"/><i class="fa fa-refresh fa-spin-custom"></i>').find("img").on('error', function() {
+                                this.ui.entityIcon.attr('title', _.escape(collectionJSON.typeName)).html('<img src="' + Utils.getEntityIconPath({ entityData: entityData }) + '"/><i class="fa fa-hourglass-half"></i>').find("img").on('error', function() {
                                     this.src = Utils.getEntityIconPath({ entityData: entityData, errorUrl: this.src });
                                 });
                             } else {
@@ -254,6 +255,7 @@ define(['require',
                     }
                     this.renderEntityDetailTableLayoutView(obj);
                     this.renderEntityUserDefineView(obj);
+                    this.renderEntityLabelDefineView(obj);
                     this.renderRelationshipLayoutView(obj);
                     this.renderAuditTableLayoutView(obj);
                     this.renderTagTableLayoutView(obj);
@@ -507,6 +509,12 @@ define(['require',
                     that.REntityUserDefineView.show(new EntityUserDefineView(obj));
                 });
             },
+            renderEntityLabelDefineView: function(obj) {
+                var that = this;
+                require(['views/entity/EntityLabelDefineView'], function(EntityLabelDefineView) {
+                    that.REntityLabelDefineView.show(new EntityLabelDefineView(obj));
+                });
+            },
             renderTagTableLayoutView: function(obj) {
                 var that = this;
                 require(['views/tag/TagDetailTableLayoutView'], function(TagDetailTableLayoutView) {
diff --git a/dashboardv3/public/js/views/entity/EntityDetailTableLayoutView.js b/dashboardv3/public/js/views/entity/EntityDetailTableLayoutView.js
index 6572292..381d99e 100644
--- a/dashboardv3/public/js/views/entity/EntityDetailTableLayoutView.js
+++ b/dashboardv3/public/js/views/entity/EntityDetailTableLayoutView.js
@@ -83,4 +83,4 @@ define(['require',
             }
         });
     return EntityDetailTableLayoutView;
-});
+});
\ No newline at end of file
diff --git a/dashboardv3/public/js/views/entity/EntityLabelDefineView.js b/dashboardv3/public/js/views/entity/EntityLabelDefineView.js
new file mode 100644
index 0000000..d69b277
--- /dev/null
+++ b/dashboardv3/public/js/views/entity/EntityLabelDefineView.js
@@ -0,0 +1,120 @@
+/**
+ * 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.
+ */
+
+define(['require',
+'backbone',
+'hbs!tmpl/entity/EntityLabelDefineView_tmpl',
+'models/VEntity',
+'utils/Utils',
+'utils/Messages',
+'utils/Enums'
+], function(require, Backbone, EntityLabelDefineView_tmpl, VEntity, Utils, Messages, Enums) {
+'use strict';
+
+    return Backbone.Marionette.LayoutView.extend({
+        _viewName: 'REntityLabelDefineView',
+        template: EntityLabelDefineView_tmpl,
+        templateHelpers: function() {
+            return {
+                swapItem: this.swapItem,
+                labels: this.labels,
+                saveLabels: this.saveLabels,
+                readOnlyEntity: this.readOnlyEntity
+            };
+        },
+        ui: {
+            addLabelOptions: "[data-id='addLabelOptions']",
+            addLabels: "[data-id='addLabels']",
+            saveLabels: "[data-id='saveLabels']"
+        },
+        events: function() {
+            var events = {};
+            events["change " + this.ui.addLabelOptions] = 'onChangeLabelChange';
+            events["click " + this.ui.addLabels] = 'handleBtnClick';
+            events["click " + this.ui.saveLabels] = 'saveUserDefinedLabels';
+            return events;
+        },
+        initialize: function(options) {
+            var self = this;
+            _.extend(this, _.pick(options, 'entity'));
+            this.swapItem = false, this.saveLabels = false;
+            this.readOnlyEntity = Enums.entityStateReadOnly[this.entity.status]
+            this.entityModel = new VEntity(this.entity);
+            this.labels = this.entity.labels || [];
+        },
+        onRender: function() {
+            this.populateLabelOptions();
+        },
+        bindEvents: function () {
+        },
+        populateLabelOptions: function() {
+            var that = this,
+            str = this.labels.map(function (label) {
+                return "<option selected > "+ label +" </option>";
+            });
+            this.ui.addLabelOptions.html(str);
+            this.ui.addLabelOptions.select2({
+                placeholder: "Select Label",
+                allowClear: true,
+                tags: true,
+                multiple: true
+            });
+        },
+        onChangeLabelChange: function () {
+            this.labels = this.ui.addLabelOptions.val();
+        },
+        handleBtnClick: function () {
+            this.swapItem = !this.swapItem;
+            this.saveLabels = this.swapItem === true ? true : false;
+            this.render();
+        },
+        saveUserDefinedLabels: function() {
+            var that = this;
+            var entityJson = that.entityModel.toJSON();
+            var payload = this.labels;
+            that.entityModel.saveEntityLabels(entityJson.guid ,{
+                data: JSON.stringify(payload),
+                type: 'POST',
+                success: function() {
+                    var msg = entityJson.labels === undefined ? 'addSuccessMessage' : 'editSuccessMessage';
+                    if (payload.length === 0) {
+                        that.entityModel.unset('labels');
+                    } else {
+                        that.entityModel.set('labels', payload);
+                    }
+                    Utils.notifySuccess({
+                        content: "User-defined labels " + Messages[msg]
+                    });
+                    that.swapItem = false;
+                    that.saveLabels = false;
+                    that.render();
+                },
+                error: function (e) {
+                    that.ui.saveLabels && that.ui.saveLabels.length > 0 &&  that.ui.saveLabels[0].setAttribute("disabled", false);
+                    Utils.notifySuccess({
+                        content: e.message
+                    });
+                },
+                complete: function () {
+                    that.ui.saveLabels && that.ui.saveLabels.length > 0 && that.ui.saveLabels[0].setAttribute("disabled", false);
+                    that.render();
+                }
+            });
+        }
+    });
+});
diff --git a/dashboardv3/public/js/views/entity/EntityUserDefineView.js b/dashboardv3/public/js/views/entity/EntityUserDefineView.js
index 588703f..a23a8fa 100644
--- a/dashboardv3/public/js/views/entity/EntityUserDefineView.js
+++ b/dashboardv3/public/js/views/entity/EntityUserDefineView.js
@@ -81,7 +81,7 @@ define(['require',
                 okText: 'Save',
                 okCloses: false,
                 cancelText: "Cancel",
-                mainClass: 'modal-lg',
+                mainClass: 'modal-md',
                 allowCancel: true,
             };
            this.setAttributeModal(modalObj);