You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ma...@apache.org on 2017/01/25 15:27:23 UTC

[1/2] incubator-atlas git commit: ATLAS-1425: Integrate Discovery/Search API in Atlas UI ATLAS-1482: UI update in assigning a tag to multiple entities using single API call

Repository: incubator-atlas
Updated Branches:
  refs/heads/master 6679c8eed -> c9c26d741


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/views/graph/LineageLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/graph/LineageLayoutView.js b/dashboardv2/public/js/views/graph/LineageLayoutView.js
index 7dae6d8..853b0bd 100644
--- a/dashboardv2/public/js/views/graph/LineageLayoutView.js
+++ b/dashboardv2/public/js/views/graph/LineageLayoutView.js
@@ -102,8 +102,7 @@ define(['require',
                     },
                     cust_error: function(model, response) {
                         that.noLineage();
-                    },
-                    complete: function() {}
+                    }
                 })
             },
             noLineage: function() {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/views/schema/SchemaLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/schema/SchemaLayoutView.js b/dashboardv2/public/js/views/schema/SchemaLayoutView.js
index 8d7dfe4..483b36c 100644
--- a/dashboardv2/public/js/views/schema/SchemaLayoutView.js
+++ b/dashboardv2/public/js/views/schema/SchemaLayoutView.js
@@ -123,9 +123,14 @@ define(['require',
                     this.schemaCollection.find(function(item) {
                         if (item.get('isEnable')) {
                             var term = [];
+                            var obj = {}
+                            obj['displayText'] = item.get("name") || item.get("qualifiedName")
+                            obj['status'] = item.get("$id$").state;
+                            obj['classificationNames'] = _.keys(item.get('$traits$'));
+                            obj['guid'] = item.get("$id$").id || item.get("$id$");
                             that.arr.push({
-                                id: item.get("$id$"),
-                                model: item
+                                id: item.get("$id$").id || item.get("$id$"),
+                                model: obj
                             });
                         }
                     });
@@ -164,6 +169,7 @@ define(['require',
                 var that = this;
                 this.$('.fontLoader').show();
                 this.schemaCollection.fetch({
+                    skipDefaultError: true,
                     success: function() {
                         that.schemaCollection.sortByKey('position');
                         that.renderTableLayoutView();
@@ -173,6 +179,9 @@ define(['require',
                     silent: true
                 });
             },
+            hideLoader: function(argument) {
+                this.$('.fontLoader').hide();
+            },
             renderTableLayoutView: function() {
                 var that = this,
                     count = 5;
@@ -318,7 +327,12 @@ define(['require',
                     className: 'searchTag',
                     formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
                         fromRaw: function(rawValue, model) {
-                            return CommonViewFunction.tagForTable(model);
+                            return CommonViewFunction.tagForTable({
+                                classificationNames: _.keys(model.get('$traits$')),
+                                guid: model.get('$id$').id || model.get('$id$') || model.get('guid'),
+                                displayText: model.get('name'),
+                                status: model.get('$id$').state
+                            });
                         }
                     })
                 };
@@ -332,7 +346,12 @@ define(['require',
                         className: 'searchTerm',
                         formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
                             fromRaw: function(rawValue, model) {
-                                var returnObject = CommonViewFunction.termTableBreadcrumbMaker(model, "schema");
+                                var returnObject = CommonViewFunction.termTableBreadcrumbMaker({
+                                    classificationNames: _.keys(model.get('$traits$')),
+                                    guid: model.get('$id$').id || model.get('$id$') || model.get('guid'),
+                                    displayText: model.get('name'),
+                                    status: model.get('$id$').state
+                                });
                                 if (returnObject.object) {
                                     that.bradCrumbList.push(returnObject.object);
                                 }
@@ -379,7 +398,8 @@ define(['require',
                         showLoader: function() {
                             that.$('.fontLoader').show();
                             that.$('.searchTable').hide();
-                        }
+                        },
+                        hideLoader: that.hideLoader.bind(that)
                     });
                     // view.saveTagData = function() {
                     //override saveTagData function 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/views/search/SearchResultLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/search/SearchResultLayoutView.js b/dashboardv2/public/js/views/search/SearchResultLayoutView.js
index 23d74a5..cbfe08e 100644
--- a/dashboardv2/public/js/views/search/SearchResultLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchResultLayoutView.js
@@ -154,9 +154,14 @@ define(['require',
                     this.searchCollection.find(function(item) {
                         if (item.get('isEnable')) {
                             var term = [];
+                            if (that.searchCollection.queryType == "DSL") {
+                                var obj = item.toJSON();
+                            } else {
+                                var obj = item.get('entity');
+                            }
                             that.arr.push({
-                                id: item.get("$id$"),
-                                model: item
+                                id: obj.guid,
+                                model: obj
                             });
                         }
                     });
@@ -170,16 +175,6 @@ define(['require',
                 });
                 this.listenTo(this.searchCollection, "error", function(value, responseData) {
                     this.$('.fontLoader').hide();
-                    var message = "Invalid expression";
-                    if (this.value && this.value.query) {
-                        message += " : " + this.value.query;
-                    }
-                    if (responseData.responseText) {
-                        message = JSON.parse(responseData.responseText).error;
-                    }
-                    Utils.notifyError({
-                        content: message
-                    });
                 }, this);
             },
             onRender: function() {
@@ -254,7 +249,7 @@ define(['require',
                             that.checkTableFetch();
                             that.offset = that.offset - that.limit;
                             if (that.firstFetch) {
-                                that.startRenderTableProcess();
+                                that.renderTableLayoutView();
                             }
                         }
                         if (that.firstFetch) {
@@ -265,7 +260,7 @@ define(['require',
                         }
                         // checking length for not rendering the table
                         if (that.searchCollection.models.length) {
-                            that.startRenderTableProcess();
+                            that.renderTableLayoutView();
                         }
                         var resultData = 'Results for <b>' + _.escape(that.searchCollection.queryParams.query) + '</b>';
                         var multiAssignDataTag = '<a href="javascript:void(0)" class="inputAssignTag multiSelectTag assignTag" style="display:none" data-id="addAssignTag"><i class="fa fa-plus"></i>' + " " + 'Assign Tag</a>';
@@ -281,14 +276,11 @@ define(['require',
                     reset: true
                 });
             },
-            startRenderTableProcess: function() {
-                this.getEntityTableColumns();
-            },
             renderTableLayoutView: function(col) {
                 var that = this,
                     count = 5;
                 require(['utils/TableLayout'], function(TableLayout) {
-                    var columns = new Backgrid.Columns(col);
+                    var columns = new Backgrid.Columns(that.getFixedDslColumn());
                     that.REntityTableLayoutView.show(new TableLayout(_.extend({}, that.commonTableOptions, {
                         globalVent: that.globalVent,
                         columns: columns
@@ -313,198 +305,85 @@ define(['require',
                     this.hideLoader();
                 }
             },
-            getEntityTableColumns: function() {
-                var that = this,
-                    col = {};
-                var responseData = this.searchCollection.responseData;
-                if (this.searchCollection.responseData) {
-                    if (responseData.dataType && responseData.dataType.typeName.indexOf('_temp') == -1) {
-                        that.renderTableLayoutView(that.getFixedDslColumn());
-                    } else {
-                        var idFound = false,
-                            fetchResultCount = 0;
-                        _.each(this.searchCollection.models, function(model) {
-                            var modelJSON = model.toJSON();
-                            var guid = "";
-                            _.each(modelJSON, function(val, key) {
-                                if (_.isObject(val)) {
-                                    if (val.id) {
-                                        model.set('id', val.id);
-                                        guid = val.id;
-                                    } else if (val.guid) {
-                                        model.set('id', val.guid);
-                                        guid = val.guid;
-                                    }
-                                } else if (key === "id") {
-                                    model.set('id', val);
-                                    guid = val;
-                                } else if (key === "guid") {
-                                    model.set('id', val);
-                                    guid = val;
-                                }
-                            });
-                            if (guid.length) {
-                                idFound = true;
-                                ++that.asyncFetchCounter;
-                                model.getEntity(guid, {
-                                    success: function(data) {
-                                        if (data.attributes) {
-                                            if (data.guid && data.attributes) {
-                                                var id = "";
-                                                id = data.guid;
-                                                if (that.searchCollection.get(id)) {
-                                                    that.searchCollection.get(id).set(data.attributes);
-                                                    that.searchCollection.get(id).set({
-                                                        '$id$': data.guid,
-                                                        '$traits$': data.classifications
-                                                    });
-                                                }
-                                            }
-                                        }
-                                    },
-                                    complete: function() {
-                                        --that.asyncFetchCounter;
-                                        if (that.asyncFetchCounter === 0) {
-                                            that.renderTableLayoutView(that.getFixedDslColumn());
-                                        }
-                                    }
-                                });
-                            }
-                        });
-                        if (idFound === false) {
-                            that.renderTableLayoutView(this.getDaynamicColumn());
-                        }
-                    }
-                }
-            },
-            getDaynamicColumn: function() {
-                var that = this,
-                    modelJSON = "",
-                    col = {};
-                modelJSON = this.searchCollection.toJSON()[0];
-                _.keys(modelJSON).map(function(key) {
-                    if (key.indexOf("$") == -1) {
-                        col[key] = {
-                            cell: 'Html',
-                            editable: false,
-                            sortable: false,
-                            orderable: true,
-                            formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
-                                fromRaw: function(rawValue, model) {
-                                    return CommonViewFunction.propertyTable({ 'notUsedKey': rawValue }, that, true);
-                                }
-                            })
-                        };
-                    }
-                });
-                that.checkTableFetch();
-                return this.searchCollection.constructor.getTableCols(col, this.searchCollection);
-            },
             getFixedDslColumn: function() {
                 var that = this,
                     nameCheck = 0,
                     col = {};
-                for (var i = 0; i < this.searchCollection.models.length; i++) {
-                    var model = this.searchCollection.models[i];
-                    if (model && (model.get('name') || model.get('qualifiedName'))) {
-                        ++nameCheck;
-                    }
-                    if (model && model.get('$id$') === undefined) {
-                        i = i > 0 ? (i - 1) : i;
-                        that.searchCollection.remove(model);
-                    }
-                }
                 col['Check'] = {
                     name: "selected",
                     label: "",
                     cell: "select-row",
                     headerCell: "select-all"
                 };
-                if (nameCheck > 0) {
-                    col['name'] = {
-                        label: "Name",
-                        cell: "html",
-                        editable: false,
-                        sortable: false,
-                        className: "searchTableName",
-                        formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
-                            fromRaw: function(rawValue, model) {
-                                var nameHtml = "";
-                                if (rawValue === undefined) {
-                                    if (model.get('qualifiedName')) {
-                                        rawValue = model.get('qualifiedName');
-                                    } else if (model.get('$id$') && model.get('$id$').qualifiedName) {
-                                        rawValue = model.get('$id$').qualifiedName;
-                                    } else {
-                                        return "";
-                                    }
-                                }
-                                if (model.get('$id$')) {
-                                    nameHtml = '<a href="#!/detailPage/' + (model.get('$id$').id || model.get('$id$')) + '">' + _.escape(rawValue) + '</a>';
-                                } else {
-                                    nameHtml = '<a>' + _.escape(rawValue) + '</a>';
-                                }
-                                if (model.get('$id$') && model.get('$id$').state && Enums.entityStateReadOnly[model.get('$id$').state]) {
-                                    nameHtml += '<button type="button" title="Deleted" class="btn btn-atlasAction btn-atlas deleteBtn"><i class="fa fa-trash"></i></button>';
-                                    return '<div class="readOnly readOnlyLink">' + nameHtml + '</div>';
-                                } else {
-                                    if (Globals.entityUpdate) {
-                                        nameHtml += '<button title="Edit" data-id="editEntityButton"  data-giud= "' + (model.get('$id$').id || model.get('$id$')) + '" class="btn btn-atlasAction btn-atlas editBtn"><i class="fa fa-pencil"></i></button>'
-                                    }
-                                    return nameHtml;
-                                }
+
+                col['displayText'] = {
+                    label: "Name",
+                    cell: "html",
+                    editable: false,
+                    sortable: false,
+                    className: "searchTableName",
+                    formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+                        fromRaw: function(rawValue, model) {
+                            if (that.searchCollection.queryType == "DSL") {
+                                var obj = model.toJSON();
+                            } else {
+                                var obj = model.get('entity');
                             }
-                        })
-                    };
-                }
-                if (nameCheck === 0) {
-                    col['typeName'] = {
-                        label: "Type Name",
-                        cell: "html",
-                        editable: false,
-                        sortable: false,
-                        formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
-                            fromRaw: function(rawValue, model) {
-                                var nameHtml = "";
-                                if (rawValue === undefined) {
-                                    if (model.get('$id$') && model.get('$id$')['$typeName$']) {
-                                        rawValue = model.get('$id$')['$typeName$'];
-                                    } else if (model.get('$typeName$')) {
-                                        rawValue = model.get('$typeName$');
-                                    } else if (model.get('typeName')) {
-                                        rawValue = model.get('typeName');
-                                    } else {
-                                        return "";
-                                    }
-                                }
-                                if (model.get('$id$')) {
-                                    nameHtml = '<a href="#!/detailPage/' + (model.get('$id$').id || model.get('$id$')) + '">' + rawValue + '</a>';
-                                } else {
-                                    nameHtml = '<a>' + rawValue + '</a>';
-                                }
-                                if (model.get('$id$') && model.get('$id$').state && Enums.entityStateReadOnly[model.get('$id$').state]) {
-                                    nameHtml += '<button type="button" title="Deleted" class="btn btn-atlasAction btn-atlas deleteBtn"><i class="fa fa-trash"></i></button>';
-                                    return '<div class="readOnly readOnlyLink">' + nameHtml + '</div>';
-                                } else {
-                                    nameHtml += '<button title="Edit" data-giud= "' + (model.get('$id$').id || model.get('$id$')) + '" class="btn btn-atlasAction btn-atlas editBtn"><i class="fa fa-pencil"></i></button>'
-                                    return nameHtml;
+                            var nameHtml = "";
+                            var name = (_.escape(obj.attributes && obj.attributes.name ? obj.attributes.name : null) || _.escape(obj.displayText) || obj.guid)
+                            if (obj.guid) {
+                                nameHtml = '<a title="' + name + '" href="#!/detailPage/' + obj.guid + '">' + name + '</a>';
+                            } else {
+                                nameHtml = '<a title="' + name + '">' + name + '</a>';
+                            }
+                            if (obj.status && Enums.entityStateReadOnly[obj.status]) {
+                                nameHtml += '<button type="button" title="Deleted" class="btn btn-atlasAction btn-atlas deleteBtn"><i class="fa fa-trash"></i></button>';
+                                return '<div class="readOnly readOnlyLink">' + nameHtml + '</div>';
+                            } else {
+                                if (Globals.entityUpdate) {
+                                    nameHtml += '<button title="Edit" data-id="editEntityButton"  data-giud= "' + obj.guid + '" class="btn btn-atlasAction btn-atlas editBtn"><i class="fa fa-pencil"></i></button>'
                                 }
+                                return nameHtml;
                             }
-                        })
-                    };
-                }
+                        }
+                    })
+                };
 
                 col['description'] = {
                     label: "Description",
                     cell: "String",
                     editable: false,
-                    sortable: false
+                    sortable: false,
+                    formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+                        fromRaw: function(rawValue, model) {
+                            if (that.searchCollection.queryType == "DSL") {
+                                var obj = model.toJSON();
+                            } else {
+                                var obj = model.get('entity');
+                            }
+                            if (obj && obj.attributes && obj.attributes.description) {
+                                return obj.attributes.description;
+                            }
+                        }
+                    })
                 };
                 col['owner'] = {
                     label: "Owner",
                     cell: "String",
                     editable: false,
-                    sortable: false
+                    sortable: false,
+                    formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+                        fromRaw: function(rawValue, model) {
+                            if (that.searchCollection.queryType == "DSL") {
+                                var obj = model.toJSON();
+                            } else {
+                                var obj = model.get('entity');
+                            }
+                            if (obj && obj.attributes && obj.attributes.owner) {
+                                return obj.attributes.owner;
+                            }
+                        }
+                    })
                 };
                 col['tag'] = {
                     label: "Tags",
@@ -515,10 +394,15 @@ define(['require',
                     className: 'searchTag',
                     formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
                         fromRaw: function(rawValue, model) {
-                            if (model.get('$id$') && model.get('$id$').state && Enums.entityStateReadOnly[model.get('$id$').state]) {
-                                return '<div class="readOnly">' + CommonViewFunction.tagForTable(model); + '</div>';
+                            if (that.searchCollection.queryType == "DSL") {
+                                var obj = model.toJSON();
                             } else {
-                                return CommonViewFunction.tagForTable(model);
+                                var obj = model.get('entity');
+                            }
+                            if (obj.status && Enums.entityStateReadOnly[obj.status]) {
+                                return '<div class="readOnly">' + CommonViewFunction.tagForTable(obj); + '</div>';
+                            } else {
+                                return CommonViewFunction.tagForTable(obj);
                             }
 
                         }
@@ -534,11 +418,16 @@ define(['require',
                         className: 'searchTerm',
                         formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
                             fromRaw: function(rawValue, model) {
-                                var returnObject = CommonViewFunction.termTableBreadcrumbMaker(model);
+                                if (that.searchCollection.queryType == "DSL") {
+                                    var obj = model.toJSON();
+                                } else {
+                                    var obj = model.get('entity');
+                                }
+                                var returnObject = CommonViewFunction.termTableBreadcrumbMaker(obj);
                                 if (returnObject.object) {
                                     that.bradCrumbList.push(returnObject.object);
                                 }
-                                if (model.get('$id$') && model.get('$id$').state && Enums.entityStateReadOnly[model.get('$id$').state]) {
+                                if (obj.status && Enums.entityStateReadOnly[obj.status]) {
                                     return '<div class="readOnly">' + returnObject.html + '</div>';
                                 } else {
                                     return returnObject.html;
@@ -560,14 +449,40 @@ define(['require',
                             that.fetchCollection();
                             that.arr = [];
                         },
+                        tagList: that.getTagList(guid, multiple),
                         showLoader: that.showLoader.bind(that),
                         hideLoader: that.hideLoader.bind(that)
                     });
-                    // view.saveTagData = function() {
-                    //override saveTagData function 
-                    // }
                 });
             },
+            getTagList: function(guid, multiple) {
+                var that = this;
+                if (!multiple || multiple.length === 0) {
+                    var modal = this.searchCollection.find(function(item) {
+                        if (that.searchCollection.queryType == "DSL") {
+                            var obj = item.toJSON();
+                        } else {
+                            var obj = item.get('entity');
+                        }
+                        if (obj.guid === guid) {
+                            return true;
+                        }
+                    });
+                    if (modal) {
+                        if (that.searchCollection.queryType == "DSL") {
+                            var obj = modal.toJSON();
+                        } else {
+                            var obj = modal.get('entity');
+                        }
+                    } else {
+                        return [];
+                    }
+                    return obj.classificationNames;
+                } else {
+                    return [];
+                }
+
+            },
             showLoader: function() {
                 this.$('.fontLoader').show();
                 this.$('.searchTable').hide();

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js b/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
index 24e1e24..3cba566 100644
--- a/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
+++ b/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
@@ -174,12 +174,20 @@ define(['require',
                         });
                         that.modal.on('ok', function() {
                             var newAttributeList = view.collection.toJSON();
-                            var saveJSON = JSON.parse(JSON.stringify(that.model.toJSON()));
-                            var oldAttributeList = saveJSON.attributeDefs;
+                            try {
+                                var saveJSON = JSON.parse(JSON.stringify(that.model.toJSON()));
+                            } catch (err) {
+                                Utils.serverErrorHandler();
+                            }
+                            if (saveJSON) {
+                                var oldAttributeList = saveJSON.attributeDefs;
+                            }
                             _.each(newAttributeList, function(obj) {
                                 oldAttributeList.push(obj);
                             });
-                            that.onSaveButton(saveJSON, Messages.addAttributeSuccessMessage);
+                            if (saveJSON) {
+                                that.onSaveButton(saveJSON, Messages.addAttributeSuccessMessage);
+                            }
                         });
                         that.modal.on('closeModal', function() {
                             that.modal.trigger('cancel');

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/views/tag/addTagModalView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/tag/addTagModalView.js b/dashboardv2/public/js/views/tag/addTagModalView.js
index dcefc5a..7317a95 100644
--- a/dashboardv2/public/js/views/tag/addTagModalView.js
+++ b/dashboardv2/public/js/views/tag/addTagModalView.js
@@ -48,7 +48,7 @@ define(['require',
          */
         initialize: function(options) {
             var that = this;
-            _.extend(this, _.pick(options, 'vent', 'modalCollection', 'guid', 'callback', 'multiple', 'showLoader', 'hideLoader'));
+            _.extend(this, _.pick(options, 'vent', 'modalCollection', 'guid', 'callback', 'multiple', 'showLoader', 'hideLoader', 'tagList'));
             this.collection = new VTagList();
             this.commonCollection = new VTagList();
             this.asyncAttrFetchCounter = 0;
@@ -68,38 +68,97 @@ define(['require',
                     var selection = $(item).data("key");
                     tagAttributes[selection] = $(item).val();
                 });
-
+                var obj = {
+                    tagName: tagName,
+                    tagAttributes: tagAttributes,
+                    guid: [],
+                    skipEntity: [],
+                    deletedEntity: []
+                }
                 if (that.multiple) {
-                    that.asyncFetchCounter = 0;
-                    for (var i = 0; i < that.multiple.length; i++) {
-                        if (i == 0) {
-                            that.showLoader();
+                    _.each(that.multiple, function(entity, i) {
+                        var name = (_.escape(entity.model.attributes && entity.model.attributes.name ? entity.model.attributes.name : null) || _.escape(entity.model.displayText) || entity.model.guid)
+                        if (Enums.entityStateReadOnly[entity.model.status]) {
+                            obj.deletedEntity.push(name);
+                        } else {
+                            if (_.indexOf(entity.model.classificationNames, tagName) === -1) {
+                                obj.guid.push(entity.model.guid)
+                            } else {
+                                obj.skipEntity.push(name);
+                            }
+
                         }
-                        var obj = {
-                            tagName: tagName,
-                            tagAttributes: tagAttributes,
-                            guid: (_.isObject(that.multiple[i].id) ? that.multiple[i].id.id : that.multiple[i].id),
-                            deletedEntity: Enums.entityStateReadOnly[that.multiple[i].id.state],
-                            entityName: that.multiple[i].model.get('name')
+                    });
+                    if (obj.deletedEntity.length) {
+                        Utils.notifyError({
+                            html: true,
+                            content: "<b>" + obj.deletedEntity.join(', ') +
+                                "</b> " + (obj.deletedEntity.length === 1 ? "entity " : "entities ") +
+                                Messages.assignDeletedEntity
+                        });
+                    }
+                    if (obj.skipEntity.length) {
+                        var text = "<b>" + obj.skipEntity.join(', ') +
+                            "</b> <br/> entities selected have already been associated with <b>" + tagName +
+                            "</b> tag, Do you want to associate the tag with other entities ?",
+                            removeCancelButton = false;
+                        if ((obj.skipEntity.length + obj.deletedEntity.length) === that.multiple.length) {
+                            text = (obj.skipEntity.length > 1 ? "All selected" : "Selected") + " entities have already been associated with <b>" + tagName + "</b> tag";
+                            removeCancelButton = true;
                         }
-                        if (obj.deletedEntity) {
-                            Utils.notifyError({
-                                content: obj.entityName + Messages.assignDeletedEntity
-                            });
-                            if (that.multiple.length === 1 || (that.multiple.length == (i + 1) && that.asyncFetchCounter == 0)) {
+                        var notifyObj = {
+                            text: text,
+                            ok: function(argument) {
+                                if (obj.guid.length) {
+                                    that.saveTagData(obj);
+                                } else {
+                                    that.hideLoader();
+                                }
+                            },
+                            cancel: function(argument) {
                                 that.hideLoader();
+                                obj = {
+                                    tagName: tagName,
+                                    tagAttributes: tagAttributes,
+                                    guid: [],
+                                    skipEntity: [],
+                                    deletedEntity: []
+                                }
                             }
-                        } else {
+                        }
+                        if (removeCancelButton) {
+                            notifyObj['confirm'] = {
+                                confirm: true,
+                                buttons: [{
+                                        text: 'Ok',
+                                        addClass: 'btn-primary',
+                                        click: function(notice) {
+                                            notice.remove();
+                                            obj = {
+                                                tagName: tagName,
+                                                tagAttributes: tagAttributes,
+                                                guid: [],
+                                                skipEntity: [],
+                                                deletedEntity: []
+                                            }
+                                        }
+                                    },
+                                    null
+                                ]
+                            }
+                        }
+
+                        Utils.notifyConfirm(notifyObj)
+                    } else {
+                        if (obj.guid.length) {
                             that.saveTagData(obj);
+                        } else {
+                            that.hideLoader();
                         }
                     }
                 } else {
-                    that.asyncFetchCounter = 0;
-                    that.saveTagData({
-                        tagName: tagName,
-                        tagAttributes: tagAttributes,
-                        guid: that.guid
-                    });
+                    obj.guid.push(that.guid);
+                    that.saveTagData(obj);
                 }
             });
             this.on('closeModal', function() {
@@ -126,13 +185,16 @@ define(['require',
             }, this);
         },
         tagsCollection: function() {
+            var that = this;
             this.collection.fullCollection.comparator = function(model) {
                 return model.get('name').toLowerCase();
             }
 
             var str = '<option selected="selected" disabled="disabled">-- Select a tag from the dropdown list --</option>';
             this.collection.fullCollection.sort().each(function(obj, key) {
-                str += '<option>' + _.escape(obj.get('name')) + '</option>';
+                if (_.indexOf(that.tagList, obj.get('name')) === -1) {
+                    str += '<option>' + _.escape(obj.get('name')) + '</option>';
+                }
             });
             this.ui.addTagOptions.html(str);
             this.ui.addTagOptions.select2({
@@ -198,26 +260,35 @@ define(['require',
         },
         saveTagData: function(options) {
             var that = this;
-            ++this.asyncFetchCounter;
             this.entityModel = new VEntity();
             var tagName = options.tagName,
                 tagAttributes = options.tagAttributes,
-                json = [{
-                    "typeName": tagName,
-                    "attributes": tagAttributes
-                }];
-            this.entityModel.saveEntity(options.guid, {
+                json = {
+                    "classification": {
+                        "typeName": tagName,
+                        "attributes": tagAttributes
+                    },
+                    "entityGuids": options.guid
+                };
+            if (this.showLoader) {
+                this.showLoader();
+            }
+            this.entityModel.saveTraitsEntity({
                 skipDefaultError: true,
                 data: JSON.stringify(json),
                 success: function(data) {
                     Utils.notifySuccess({
-                        content: "Tag " + tagName + " has been added to entity"
+                        content: "Tag " + tagName + " has been added to " + (that.multiple ? "entities" : "entity")
                     });
                     if (options.modalCollection) {
                         options.modalCollection.fetch({ reset: true });
                     }
+                    if (that.callback) {
+                        that.callback();
+                    }
+
                 },
-                    cust_error: function(model, response) {
+                cust_error: function(model, response) {
                     var message = "Tag " + tagName + " could not be added";
                     if (response && response.responseJSON) {
                         message = response.responseJSON.errorMessage;
@@ -225,12 +296,10 @@ define(['require',
                     Utils.notifyError({
                         content: message
                     });
-                },
-                complete: function() {
-                    --that.asyncFetchCounter;
-                    if (that.callback && that.asyncFetchCounter === 0) {
-                        that.callback();
+                    if (that.hideLoader) {
+                        that.hideLoader();
                     }
+
                 }
             });
         },

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/release-log.txt
----------------------------------------------------------------------
diff --git a/release-log.txt b/release-log.txt
index dc7d12e..5ca51a8 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -9,6 +9,8 @@ ATLAS-1060 Add composite indexes for exact match performance improvements for al
 ATLAS-1127 Modify creation and modification timestamps to Date instead of Long(sumasai)
 
 ALL CHANGES:
+ATLAS-1425 Integrate Discovery/Search API in Atlas UI (kevalbhatt via mneethiraj)
+ATLAS-1482 UI update in assigning a tag to multiple entities using single API call (kevalbhatt via mneethiraj)
 ATLAS-1486 UI updates to handle errors from V2 APIs (Kalyanikashikar via mneethiraj)
 ATLAS-1436 Metrics collection using gremlin (apoorvnaik via mneethiraj)
 ATLAS-1489 Show create/edit entity button based on role (Kalyanikashikar via kevalbhatt)



[2/2] incubator-atlas git commit: ATLAS-1425: Integrate Discovery/Search API in Atlas UI ATLAS-1482: UI update in assigning a tag to multiple entities using single API call

Posted by ma...@apache.org.
ATLAS-1425: Integrate Discovery/Search API in Atlas UI
ATLAS-1482: UI update in assigning a tag to multiple entities using single API call

Signed-off-by: Madhan Neethiraj <ma...@apache.org>


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

Branch: refs/heads/master
Commit: c9c26d74187532f6f6922443f52ffa2739e81c86
Parents: 6679c8e
Author: kevalbhatt <kb...@apache.org>
Authored: Wed Jan 25 15:48:11 2017 +0530
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Wed Jan 25 07:26:42 2017 -0800

----------------------------------------------------------------------
 dashboardv2/public/css/scss/main.scss           |   3 +-
 dashboardv2/public/css/scss/override.scss       |   4 +
 dashboardv2/public/index.html                   |   2 +-
 dashboardv2/public/js/collection/VSearchList.js |  29 +-
 .../js/external_lib/pnotify.custom.min.css      |   1 -
 .../js/external_lib/pnotify.custom.min.js       |  48 ---
 .../js/external_lib/pnotify/pnotify.buttons.js  |   8 +
 .../js/external_lib/pnotify/pnotify.confirm.js  |   7 +
 .../external_lib/pnotify/pnotify.custom.min.css |   1 +
 .../public/js/external_lib/pnotify/pnotify.js   |  31 ++
 dashboardv2/public/js/main.js                   |   4 +-
 dashboardv2/public/js/models/VEntity.js         |   4 +-
 dashboardv2/public/js/modules/atlasLogin.js     | 187 ++++++------
 .../public/js/utils/CommonViewFunction.js       |  84 ++---
 dashboardv2/public/js/utils/Messages.js         |   2 +-
 dashboardv2/public/js/utils/UrlLinks.js         |  10 +-
 dashboardv2/public/js/utils/Utils.js            |  47 ++-
 .../views/detail_page/DetailPageLayoutView.js   |  32 +-
 .../public/js/views/graph/LineageLayoutView.js  |   3 +-
 .../public/js/views/schema/SchemaLayoutView.js  |  30 +-
 .../js/views/search/SearchResultLayoutView.js   | 305 +++++++------------
 .../views/tag/TagAttributeDetailLayoutView.js   |  14 +-
 .../public/js/views/tag/addTagModalView.js      | 145 ++++++---
 release-log.txt                                 |   2 +
 24 files changed, 531 insertions(+), 472 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/css/scss/main.scss
----------------------------------------------------------------------
diff --git a/dashboardv2/public/css/scss/main.scss b/dashboardv2/public/css/scss/main.scss
index 1d10bab..e56173c 100644
--- a/dashboardv2/public/css/scss/main.scss
+++ b/dashboardv2/public/css/scss/main.scss
@@ -261,7 +261,8 @@ ul {
 }
 
 .readOnlyLink {
-    display: inline-block;
+    text-overflow: ellipsis;
+    overflow: hidden;
     .deleteBtn {
         padding: 0px 5px;
     }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/css/scss/override.scss
----------------------------------------------------------------------
diff --git a/dashboardv2/public/css/scss/override.scss b/dashboardv2/public/css/scss/override.scss
index b0f5c7f..6c8ae37 100644
--- a/dashboardv2/public/css/scss/override.scss
+++ b/dashboardv2/public/css/scss/override.scss
@@ -245,3 +245,7 @@
 .tab-content > .tab-pane.active {
     overflow-x: hidden;
 }
+
+.ui-pnotify-text {
+    word-break: break-all;
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/index.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/index.html b/dashboardv2/public/index.html
index 36ddef5..9f1d941 100644
--- a/dashboardv2/public/index.html
+++ b/dashboardv2/public/index.html
@@ -50,7 +50,7 @@
     <link rel="stylesheet" type="text/css" href="js/external_lib/jquery-ui/jquery-ui.min.css">
     <link href="css/bootstrap-sidebar.css" rel="stylesheet">
     <link href="js/libs/font-awesome/css/font-awesome.min.css" rel="stylesheet">
-    <link href="js/external_lib/pnotify.custom.min.css" rel="stylesheet">
+    <link href="js/external_lib/pnotify/pnotify.custom.min.css" rel="stylesheet">
     <link href="css/style.css" rel="stylesheet">
 </head>
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/collection/VSearchList.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/collection/VSearchList.js b/dashboardv2/public/js/collection/VSearchList.js
index 2ec4952..60fe8fb 100644
--- a/dashboardv2/public/js/collection/VSearchList.js
+++ b/dashboardv2/public/js/collection/VSearchList.js
@@ -32,30 +32,15 @@ define(['require',
 
             initialize: function() {
                 this.modelName = 'VSearch';
-                this.modelAttrName = 'results';
+                this.modelAttrName = '';
             },
             parseRecords: function(resp, options) {
-                this.responseData = {
-                    dataType: resp.dataType,
-                    query: resp.query,
-                    queryType: resp.queryType,
-                    requestId: resp.requestId
-                };
-                try {
-                    if (!this.modelAttrName) {
-                        throw new Error("this.modelAttrName not defined for " + this);
-                    }
-                    var list = _.reject(resp[this.modelAttrName], _.isNull);
-                    _.each(list, function(obj) {
-                        if (!obj.id) {
-                            if (obj['$id$'] && obj['$id$'].id) {
-                                obj.id = obj['$id$'].id
-                            }
-                        }
-                    })
-                    return list;
-                } catch (e) {
-                    console.log(e);
+                this.queryType = resp.queryType;
+                this.queryText = resp.queryText;
+                if (resp.queryType && resp.queryType == "DSL") {
+                    return resp.entities ? resp.entities : [];
+                } else {
+                    return resp.fullTextResult ? resp.fullTextResult : [];
                 }
             },
         },

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/external_lib/pnotify.custom.min.css
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/external_lib/pnotify.custom.min.css b/dashboardv2/public/js/external_lib/pnotify.custom.min.css
deleted file mode 100644
index c4c9bf4..0000000
--- a/dashboardv2/public/js/external_lib/pnotify.custom.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.ui-pnotify{top:36px;right:36px;position:absolute;height:auto;z-index:2}body>.ui-pnotify{position:fixed;z-index:100040}.ui-pnotify-modal-overlay{background-color:rgba(0,0,0,.4);top:0;left:0;position:absolute;height:100%;width:100%;z-index:1}body>.ui-pnotify-modal-overlay{position:fixed;z-index:100039}.ui-pnotify.ui-pnotify-in{display:block!important}.ui-pnotify.ui-pnotify-move{transition:left .5s ease,top .5s ease,right .5s ease,bottom .5s ease}.ui-pnotify.ui-pnotify-fade-slow{transition:opacity .6s linear;opacity:0}.ui-pnotify.ui-pnotify-fade-slow.ui-pnotify.ui-pnotify-move{transition:opacity .6s linear,left .5s ease,top .5s ease,right .5s ease,bottom .5s ease}.ui-pnotify.ui-pnotify-fade-normal{transition:opacity .4s linear;opacity:0}.ui-pnotify.ui-pnotify-fade-normal.ui-pnotify.ui-pnotify-move{transition:opacity .4s linear,left .5s ease,top .5s ease,right .5s ease,bottom .5s ease}.ui-pnotify.ui-pnotify-fade-fast{transition:opacity .2s linear;opacity:0}.ui-pnotify.ui-pnotify-fade-f
 ast.ui-pnotify.ui-pnotify-move{transition:opacity .2s linear,left .5s ease,top .5s ease,right .5s ease,bottom .5s ease}.ui-pnotify.ui-pnotify-fade-in{opacity:1}.ui-pnotify .ui-pnotify-shadow{-webkit-box-shadow:0 6px 28px 0 rgba(0,0,0,.1);-moz-box-shadow:0 6px 28px 0 rgba(0,0,0,.1);box-shadow:0 6px 28px 0 rgba(0,0,0,.1)}.ui-pnotify-container{background-position:0 0;padding:.8em;height:100%;margin:0}.ui-pnotify-container:after{content:" ";visibility:hidden;display:block;height:0;clear:both}.ui-pnotify-container.ui-pnotify-sharp{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.ui-pnotify-title{display:block;margin-bottom:.4em;margin-top:0}.ui-pnotify-text{display:block}.ui-pnotify-icon,.ui-pnotify-icon span{display:block;float:left;margin-right:.2em}.ui-pnotify.stack-bottomleft,.ui-pnotify.stack-topleft{left:25px;right:auto}.ui-pnotify.stack-bottomleft,.ui-pnotify.stack-bottomright{bottom:25px;top:auto}.ui-pnotify.stack-modal{left:50%;right:auto;margin-left:-150px}.brightt
 heme{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.brighttheme.ui-pnotify-container{padding:18px}.brighttheme .ui-pnotify-title{margin-bottom:12px}.brighttheme-notice{background-color:#FFFFA2;border:0 solid #FF0;color:#4F4F00}.brighttheme-info{background-color:#8FCEDD;border:0 solid #0286A5;color:#012831}.brighttheme-success{background-color:#AFF29A;border:0 solid #35DB00;color:#104300}.brighttheme-error{background-color:#FFABA2;background-image:repeating-linear-gradient(135deg,transparent,transparent 35px,rgba(255,255,255,.3) 35px,rgba(255,255,255,.3) 70px);border:0 solid #FF1800;color:#4F0800}.brighttheme-icon-closer,.brighttheme-icon-info,.brighttheme-icon-notice,.brighttheme-icon-sticker,.brighttheme-icon-success{position:relative;width:16px;height:16px;font-size:12px;font-weight:700;line-height:16px;font-family:"Courier New",Courier,monospace;border-radius:50%}.brighttheme-icon-closer:after,.brighttheme-icon-info:after,.brighttheme-icon-notice:after,.brighttheme
 -icon-sticker:after,.brighttheme-icon-success:after{position:absolute;top:0;left:4px}.brighttheme-icon-notice{background-color:#2E2E00;color:#FFFFA2;margin-top:2px}.brighttheme-icon-notice:after{content:"!"}.brighttheme-icon-info{background-color:#012831;color:#8FCEDD;margin-top:2px}.brighttheme-icon-info:after{content:"i"}.brighttheme-icon-success{background-color:#104300;color:#AFF29A;margin-top:2px}.brighttheme-icon-success:after{content:"\002713"}.brighttheme-icon-error{position:relative;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:16px solid #2E0400;font-size:0;line-height:0;color:#FFABA2;margin-top:1px}.brighttheme-icon-error:after{position:absolute;top:1px;left:-4px;font-size:12px;font-weight:700;line-height:16px;font-family:"Courier New",Courier,monospace;content:"!"}.brighttheme-icon-closer,.brighttheme-icon-sticker{display:inline-block}.brighttheme-icon-closer:after{top:-4px;content:"\002715"}.brighttheme-icon-sticker:
 after{top:-5px;content:"\01D1BC";-moz-transform:rotate(-90deg);-webkit-transform:rotate(-90deg);-o-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.brighttheme-icon-sticker.brighttheme-icon-stuck:after{-moz-transform:rotate(180deg);-webkit-transform:rotate(180deg);-o-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.brighttheme .ui-pnotify-action-bar{padding-top:12px}.brighttheme .ui-pnotify-action-bar input,.brighttheme .ui-pnotify-action-bar textarea{display:block;width:100%;margin-bottom:12px!important}.brighttheme .ui-pnotify-action-button{text-transform:uppercase;font-weight:700;padding:4px 8px;border:none;background:0 0}.brighttheme .ui-pnotify-action-button.btn-primary{border:none;border-radius:0}.brighttheme-notice .ui-pnotify-action-button.btn-primary{background-color:#FF0;color:#4F4F00}.brighttheme-info .ui-pnotify-action-button.btn-primary{background-color:#0286A5;color:#012831}.brighttheme-success .ui-pnotify-a
 ction-button.btn-primary{background-color:#35DB00;color:#104300}.brighttheme-error .ui-pnotify-action-button.btn-primary{background-color:#FF1800;color:#4F0800}.ui-pnotify-closer,.ui-pnotify-sticker{float:right;margin-left:.2em}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/external_lib/pnotify.custom.min.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/external_lib/pnotify.custom.min.js b/dashboardv2/public/js/external_lib/pnotify.custom.min.js
deleted file mode 100644
index 9c5f67e..0000000
--- a/dashboardv2/public/js/external_lib/pnotify.custom.min.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-PNotify 3.0.0 sciactive.com/pnotify/
-(C) 2015 Hunter Perrin; Google, Inc.
-license Apache-2.0
-*/
-(function(b,k){"function"===typeof define&&define.amd?define("pnotify",["jquery"],function(q){return k(q,b)}):"object"===typeof exports&&"undefined"!==typeof module?module.exports=k(require("jquery"),global||b):b.PNotify=k(b.jQuery,b)})(this,function(b,k){var q=function(l){var k={dir1:"down",dir2:"left",push:"bottom",spacing1:36,spacing2:36,context:b("body"),modal:!1},g,h,n=b(l),r=function(){h=b("body");d.prototype.options.stack.context=h;n=b(l);n.bind("resize",function(){g&&clearTimeout(g);g=setTimeout(function(){d.positionAll(!0)},
-10)})},s=function(c){var a=b("<div />",{"class":"ui-pnotify-modal-overlay"});a.prependTo(c.context);c.overlay_close&&a.click(function(){d.removeStack(c)});return a},d=function(c){this.parseOptions(c);this.init()};b.extend(d.prototype,{version:"3.0.0",options:{title:!1,title_escape:!1,text:!1,text_escape:!1,styling:"brighttheme",addclass:"",cornerclass:"",auto_display:!0,width:"300px",min_height:"16px",type:"notice",icon:!0,animation:"fade",animate_speed:"normal",shadow:!0,hide:!0,delay:8E3,mouse_reset:!0,
-remove:!0,insert_brs:!0,destroy:!0,stack:k},modules:{},runModules:function(c,a){var p,b;for(b in this.modules)p="object"===typeof a&&b in a?a[b]:a,"function"===typeof this.modules[b][c]&&(this.modules[b].notice=this,this.modules[b].options="object"===typeof this.options[b]?this.options[b]:{},this.modules[b][c](this,"object"===typeof this.options[b]?this.options[b]:{},p))},state:"initializing",timer:null,animTimer:null,styles:null,elem:null,container:null,title_container:null,text_container:null,animating:!1,
-timerHide:!1,init:function(){var c=this;this.modules={};b.extend(!0,this.modules,d.prototype.modules);this.styles="object"===typeof this.options.styling?this.options.styling:d.styling[this.options.styling];this.elem=b("<div />",{"class":"ui-pnotify "+this.options.addclass,css:{display:"none"},"aria-live":"assertive","aria-role":"alertdialog",mouseenter:function(a){if(c.options.mouse_reset&&"out"===c.animating){if(!c.timerHide)return;c.cancelRemove()}c.options.hide&&c.options.mouse_reset&&c.cancelRemove()},
-mouseleave:function(a){c.options.hide&&c.options.mouse_reset&&"out"!==c.animating&&c.queueRemove();d.positionAll()}});"fade"===this.options.animation&&this.elem.addClass("ui-pnotify-fade-"+this.options.animate_speed);this.container=b("<div />",{"class":this.styles.container+" ui-pnotify-container "+("error"===this.options.type?this.styles.error:"info"===this.options.type?this.styles.info:"success"===this.options.type?this.styles.success:this.styles.notice),role:"alert"}).appendTo(this.elem);""!==
-this.options.cornerclass&&this.container.removeClass("ui-corner-all").addClass(this.options.cornerclass);this.options.shadow&&this.container.addClass("ui-pnotify-shadow");!1!==this.options.icon&&b("<div />",{"class":"ui-pnotify-icon"}).append(b("<span />",{"class":!0===this.options.icon?"error"===this.options.type?this.styles.error_icon:"info"===this.options.type?this.styles.info_icon:"success"===this.options.type?this.styles.success_icon:this.styles.notice_icon:this.options.icon})).prependTo(this.container);
-this.title_container=b("<h4 />",{"class":"ui-pnotify-title"}).appendTo(this.container);!1===this.options.title?this.title_container.hide():this.options.title_escape?this.title_container.text(this.options.title):this.title_container.html(this.options.title);this.text_container=b("<div />",{"class":"ui-pnotify-text","aria-role":"alert"}).appendTo(this.container);!1===this.options.text?this.text_container.hide():this.options.text_escape?this.text_container.text(this.options.text):this.text_container.html(this.options.insert_brs?
-String(this.options.text).replace(/\n/g,"<br />"):this.options.text);"string"===typeof this.options.width&&this.elem.css("width",this.options.width);"string"===typeof this.options.min_height&&this.container.css("min-height",this.options.min_height);d.notices="top"===this.options.stack.push?b.merge([this],d.notices):b.merge(d.notices,[this]);"top"===this.options.stack.push&&this.queuePosition(!1,1);this.options.stack.animation=!1;this.runModules("init");this.options.auto_display&&this.open();return this},
-update:function(c){var a=this.options;this.parseOptions(a,c);this.elem.removeClass("ui-pnotify-fade-slow ui-pnotify-fade-normal ui-pnotify-fade-fast");"fade"===this.options.animation&&this.elem.addClass("ui-pnotify-fade-"+this.options.animate_speed);this.options.cornerclass!==a.cornerclass&&this.container.removeClass("ui-corner-all "+a.cornerclass).addClass(this.options.cornerclass);this.options.shadow!==a.shadow&&(this.options.shadow?this.container.addClass("ui-pnotify-shadow"):this.container.removeClass("ui-pnotify-shadow"));
-!1===this.options.addclass?this.elem.removeClass(a.addclass):this.options.addclass!==a.addclass&&this.elem.removeClass(a.addclass).addClass(this.options.addclass);!1===this.options.title?this.title_container.slideUp("fast"):this.options.title!==a.title&&(this.options.title_escape?this.title_container.text(this.options.title):this.title_container.html(this.options.title),!1===a.title&&this.title_container.slideDown(200));!1===this.options.text?this.text_container.slideUp("fast"):this.options.text!==
-a.text&&(this.options.text_escape?this.text_container.text(this.options.text):this.text_container.html(this.options.insert_brs?String(this.options.text).replace(/\n/g,"<br />"):this.options.text),!1===a.text&&this.text_container.slideDown(200));this.options.type!==a.type&&this.container.removeClass(this.styles.error+" "+this.styles.notice+" "+this.styles.success+" "+this.styles.info).addClass("error"===this.options.type?this.styles.error:"info"===this.options.type?this.styles.info:"success"===this.options.type?
-this.styles.success:this.styles.notice);if(this.options.icon!==a.icon||!0===this.options.icon&&this.options.type!==a.type)this.container.find("div.ui-pnotify-icon").remove(),!1!==this.options.icon&&b("<div />",{"class":"ui-pnotify-icon"}).append(b("<span />",{"class":!0===this.options.icon?"error"===this.options.type?this.styles.error_icon:"info"===this.options.type?this.styles.info_icon:"success"===this.options.type?this.styles.success_icon:this.styles.notice_icon:this.options.icon})).prependTo(this.container);
-this.options.width!==a.width&&this.elem.animate({width:this.options.width});this.options.min_height!==a.min_height&&this.container.animate({minHeight:this.options.min_height});this.options.hide?a.hide||this.queueRemove():this.cancelRemove();this.queuePosition(!0);this.runModules("update",a);return this},open:function(){this.state="opening";this.runModules("beforeOpen");var c=this;this.elem.parent().length||this.elem.appendTo(this.options.stack.context?this.options.stack.context:h);"top"!==this.options.stack.push&&
-this.position(!0);this.animateIn(function(){c.queuePosition(!0);c.options.hide&&c.queueRemove();c.state="open";c.runModules("afterOpen")});return this},remove:function(c){this.state="closing";this.timerHide=!!c;this.runModules("beforeClose");var a=this;this.timer&&(l.clearTimeout(this.timer),this.timer=null);this.animateOut(function(){a.state="closed";a.runModules("afterClose");a.queuePosition(!0);a.options.remove&&a.elem.detach();a.runModules("beforeDestroy");if(a.options.destroy&&null!==d.notices){var c=
-b.inArray(a,d.notices);-1!==c&&d.notices.splice(c,1)}a.runModules("afterDestroy")});return this},get:function(){return this.elem},parseOptions:function(c,a){this.options=b.extend(!0,{},d.prototype.options);this.options.stack=d.prototype.options.stack;for(var p=[c,a],m,f=0;f<p.length;f++){m=p[f];if("undefined"===typeof m)break;if("object"!==typeof m)this.options.text=m;else for(var e in m)this.modules[e]?b.extend(!0,this.options[e],m[e]):this.options[e]=m[e]}},animateIn:function(c){this.animating=
-"in";var a=this;c=function(){a.animTimer&&clearTimeout(a.animTimer);"in"===a.animating&&(a.elem.is(":visible")?(this&&this.call(),a.animating=!1):a.animTimer=setTimeout(c,40))}.bind(c);"fade"===this.options.animation?(this.elem.one("webkitTransitionEnd mozTransitionEnd MSTransitionEnd oTransitionEnd transitionend",c).addClass("ui-pnotify-in"),this.elem.css("opacity"),this.elem.addClass("ui-pnotify-fade-in"),this.animTimer=setTimeout(c,650)):(this.elem.addClass("ui-pnotify-in"),c())},animateOut:function(c){this.animating=
-"out";var a=this;c=function(){a.animTimer&&clearTimeout(a.animTimer);"out"===a.animating&&("0"!=a.elem.css("opacity")&&a.elem.is(":visible")?a.animTimer=setTimeout(c,40):(a.elem.removeClass("ui-pnotify-in"),this&&this.call(),a.animating=!1))}.bind(c);"fade"===this.options.animation?(this.elem.one("webkitTransitionEnd mozTransitionEnd MSTransitionEnd oTransitionEnd transitionend",c).removeClass("ui-pnotify-fade-in"),this.animTimer=setTimeout(c,650)):(this.elem.removeClass("ui-pnotify-in"),c())},position:function(c){var a=
-this.options.stack,b=this.elem;"undefined"===typeof a.context&&(a.context=h);if(a){"number"!==typeof a.nextpos1&&(a.nextpos1=a.firstpos1);"number"!==typeof a.nextpos2&&(a.nextpos2=a.firstpos2);"number"!==typeof a.addpos2&&(a.addpos2=0);var d=!b.hasClass("ui-pnotify-in");if(!d||c){a.modal&&(a.overlay?a.overlay.show():a.overlay=s(a));b.addClass("ui-pnotify-move");var f;switch(a.dir1){case "down":f="top";break;case "up":f="bottom";break;case "left":f="right";break;case "right":f="left"}c=parseInt(b.css(f).replace(/(?:\..*|[^0-9.])/g,
-""));isNaN(c)&&(c=0);"undefined"!==typeof a.firstpos1||d||(a.firstpos1=c,a.nextpos1=a.firstpos1);var e;switch(a.dir2){case "down":e="top";break;case "up":e="bottom";break;case "left":e="right";break;case "right":e="left"}c=parseInt(b.css(e).replace(/(?:\..*|[^0-9.])/g,""));isNaN(c)&&(c=0);"undefined"!==typeof a.firstpos2||d||(a.firstpos2=c,a.nextpos2=a.firstpos2);if("down"===a.dir1&&a.nextpos1+b.height()>(a.context.is(h)?n.height():a.context.prop("scrollHeight"))||"up"===a.dir1&&a.nextpos1+b.height()>
-(a.context.is(h)?n.height():a.context.prop("scrollHeight"))||"left"===a.dir1&&a.nextpos1+b.width()>(a.context.is(h)?n.width():a.context.prop("scrollWidth"))||"right"===a.dir1&&a.nextpos1+b.width()>(a.context.is(h)?n.width():a.context.prop("scrollWidth")))a.nextpos1=a.firstpos1,a.nextpos2+=a.addpos2+("undefined"===typeof a.spacing2?25:a.spacing2),a.addpos2=0;"number"===typeof a.nextpos2&&(a.animation?b.css(e,a.nextpos2+"px"):(b.removeClass("ui-pnotify-move"),b.css(e,a.nextpos2+"px"),b.css(e),b.addClass("ui-pnotify-move")));
-switch(a.dir2){case "down":case "up":b.outerHeight(!0)>a.addpos2&&(a.addpos2=b.height());break;case "left":case "right":b.outerWidth(!0)>a.addpos2&&(a.addpos2=b.width())}"number"===typeof a.nextpos1&&(a.animation?b.css(f,a.nextpos1+"px"):(b.removeClass("ui-pnotify-move"),b.css(f,a.nextpos1+"px"),b.css(f),b.addClass("ui-pnotify-move")));switch(a.dir1){case "down":case "up":a.nextpos1+=b.height()+("undefined"===typeof a.spacing1?25:a.spacing1);break;case "left":case "right":a.nextpos1+=b.width()+("undefined"===
-typeof a.spacing1?25:a.spacing1)}}return this}},queuePosition:function(b,a){g&&clearTimeout(g);a||(a=10);g=setTimeout(function(){d.positionAll(b)},a);return this},cancelRemove:function(){this.timer&&l.clearTimeout(this.timer);this.animTimer&&l.clearTimeout(this.animTimer);"closing"===this.state&&(this.state="open",this.animating=!1,this.elem.addClass("ui-pnotify-in"),"fade"===this.options.animation&&this.elem.addClass("ui-pnotify-fade-in"));return this},queueRemove:function(){var b=this;this.cancelRemove();
-this.timer=l.setTimeout(function(){b.remove(!0)},isNaN(this.options.delay)?0:this.options.delay);return this}});b.extend(d,{notices:[],reload:q,removeAll:function(){b.each(d.notices,function(){this.remove&&this.remove(!1)})},removeStack:function(c){b.each(d.notices,function(){this.remove&&this.options.stack===c&&this.remove(!1)})},positionAll:function(c){g&&clearTimeout(g);g=null;if(d.notices&&d.notices.length)b.each(d.notices,function(){var a=this.options.stack;a&&(a.overlay&&a.overlay.hide(),a.nextpos1=
-a.firstpos1,a.nextpos2=a.firstpos2,a.addpos2=0,a.animation=c)}),b.each(d.notices,function(){this.position()});else{var a=d.prototype.options.stack;a&&(delete a.nextpos1,delete a.nextpos2)}},styling:{brighttheme:{container:"brighttheme",notice:"brighttheme-notice",notice_icon:"brighttheme-icon-notice",info:"brighttheme-info",info_icon:"brighttheme-icon-info",success:"brighttheme-success",success_icon:"brighttheme-icon-success",error:"brighttheme-error",error_icon:"brighttheme-icon-error"},jqueryui:{container:"ui-widget ui-widget-content ui-corner-all",
-notice:"ui-state-highlight",notice_icon:"ui-icon ui-icon-info",info:"",info_icon:"ui-icon ui-icon-info",success:"ui-state-default",success_icon:"ui-icon ui-icon-circle-check",error:"ui-state-error",error_icon:"ui-icon ui-icon-alert"},bootstrap3:{container:"alert",notice:"alert-warning",notice_icon:"glyphicon glyphicon-exclamation-sign",info:"alert-info",info_icon:"glyphicon glyphicon-info-sign",success:"alert-success",success_icon:"glyphicon glyphicon-ok-sign",error:"alert-danger",error_icon:"glyphicon glyphicon-warning-sign"}}});
-d.styling.fontawesome=b.extend({},d.styling.bootstrap3);b.extend(d.styling.fontawesome,{notice_icon:"fa fa-exclamation-circle",info_icon:"fa fa-info",success_icon:"fa fa-check",error_icon:"fa fa-warning"});l.document.body?r():b(r);return d};return q(k)});
-(function(d,e){"function"===typeof define&&define.amd?define("pnotify.buttons",["jquery","pnotify"],e):"object"===typeof exports&&"undefined"!==typeof module?module.exports=e(require("jquery"),require("./pnotify")):e(d.jQuery,d.PNotify)})(this,function(d,e){e.prototype.options.buttons={closer:!0,closer_hover:!0,sticker:!0,sticker_hover:!0,show_on_nonblock:!1,labels:{close:"Close",stick:"Stick",unstick:"Unstick"},classes:{closer:null,pin_up:null,pin_down:null}};e.prototype.modules.buttons={closer:null,
-sticker:null,init:function(a,b){var c=this;a.elem.on({mouseenter:function(b){!c.options.sticker||a.options.nonblock&&a.options.nonblock.nonblock&&!c.options.show_on_nonblock||c.sticker.trigger("pnotify:buttons:toggleStick").css("visibility","visible");!c.options.closer||a.options.nonblock&&a.options.nonblock.nonblock&&!c.options.show_on_nonblock||c.closer.css("visibility","visible")},mouseleave:function(a){c.options.sticker_hover&&c.sticker.css("visibility","hidden");c.options.closer_hover&&c.closer.css("visibility",
-"hidden")}});this.sticker=d("<div />",{"class":"ui-pnotify-sticker","aria-role":"button","aria-pressed":a.options.hide?"false":"true",tabindex:"0",title:a.options.hide?b.labels.stick:b.labels.unstick,css:{cursor:"pointer",visibility:b.sticker_hover?"hidden":"visible"},click:function(){a.options.hide=!a.options.hide;a.options.hide?a.queueRemove():a.cancelRemove();d(this).trigger("pnotify:buttons:toggleStick")}}).bind("pnotify:buttons:toggleStick",function(){var b=null===c.options.classes.pin_up?a.styles.pin_up:
-c.options.classes.pin_up,e=null===c.options.classes.pin_down?a.styles.pin_down:c.options.classes.pin_down;d(this).attr("title",a.options.hide?c.options.labels.stick:c.options.labels.unstick).children().attr("class","").addClass(a.options.hide?b:e).attr("aria-pressed",a.options.hide?"false":"true")}).append("<span />").trigger("pnotify:buttons:toggleStick").prependTo(a.container);(!b.sticker||a.options.nonblock&&a.options.nonblock.nonblock&&!b.show_on_nonblock)&&this.sticker.css("display","none");
-this.closer=d("<div />",{"class":"ui-pnotify-closer","aria-role":"button",tabindex:"0",title:b.labels.close,css:{cursor:"pointer",visibility:b.closer_hover?"hidden":"visible"},click:function(){a.remove(!1);c.sticker.css("visibility","hidden");c.closer.css("visibility","hidden")}}).append(d("<span />",{"class":null===b.classes.closer?a.styles.closer:b.classes.closer})).prependTo(a.container);(!b.closer||a.options.nonblock&&a.options.nonblock.nonblock&&!b.show_on_nonblock)&&this.closer.css("display",
-"none")},update:function(a,b){!b.closer||a.options.nonblock&&a.options.nonblock.nonblock&&!b.show_on_nonblock?this.closer.css("display","none"):b.closer&&this.closer.css("display","block");!b.sticker||a.options.nonblock&&a.options.nonblock.nonblock&&!b.show_on_nonblock?this.sticker.css("display","none"):b.sticker&&this.sticker.css("display","block");this.sticker.trigger("pnotify:buttons:toggleStick");this.closer.find("span").attr("class","").addClass(null===b.classes.closer?a.styles.closer:b.classes.closer);
-b.sticker_hover?this.sticker.css("visibility","hidden"):a.options.nonblock&&a.options.nonblock.nonblock&&!b.show_on_nonblock||this.sticker.css("visibility","visible");b.closer_hover?this.closer.css("visibility","hidden"):a.options.nonblock&&a.options.nonblock.nonblock&&!b.show_on_nonblock||this.closer.css("visibility","visible")}};d.extend(e.styling.brighttheme,{closer:"brighttheme-icon-closer",pin_up:"brighttheme-icon-sticker",pin_down:"brighttheme-icon-sticker brighttheme-icon-stuck"});d.extend(e.styling.jqueryui,
-{closer:"ui-icon ui-icon-close",pin_up:"ui-icon ui-icon-pin-w",pin_down:"ui-icon ui-icon-pin-s"});d.extend(e.styling.bootstrap2,{closer:"icon-remove",pin_up:"icon-pause",pin_down:"icon-play"});d.extend(e.styling.bootstrap3,{closer:"glyphicon glyphicon-remove",pin_up:"glyphicon glyphicon-pause",pin_down:"glyphicon glyphicon-play"});d.extend(e.styling.fontawesome,{closer:"fa fa-times",pin_up:"fa fa-pause",pin_down:"fa fa-play"})});
-(function(b,a){"function"===typeof define&&define.amd?define("pnotify.callbacks",["jquery","pnotify"],a):"object"===typeof exports&&"undefined"!==typeof module?module.exports=a(require("jquery"),require("./pnotify")):a(b.jQuery,b.PNotify)})(this,function(b,a){var c=a.prototype.init,d=a.prototype.open,e=a.prototype.remove;a.prototype.init=function(){this.options.before_init&&this.options.before_init(this.options);c.apply(this,arguments);this.options.after_init&&this.options.after_init(this)};a.prototype.open=
-function(){var a;this.options.before_open&&(a=this.options.before_open(this));!1!==a&&(d.apply(this,arguments),this.options.after_open&&this.options.after_open(this))};a.prototype.remove=function(a){var b;this.options.before_close&&(b=this.options.before_close(this,a));!1!==b&&(e.apply(this,arguments),this.options.after_close&&this.options.after_close(this,a))}});
-(function(e,c){"function"===typeof define&&define.amd?define("pnotify.confirm",["jquery","pnotify"],c):"object"===typeof exports&&"undefined"!==typeof module?module.exports=c(require("jquery"),require("./pnotify")):c(e.jQuery,e.PNotify)})(this,function(e,c){c.prototype.options.confirm={confirm:!1,prompt:!1,prompt_class:"",prompt_default:"",prompt_multi_line:!1,align:"right",buttons:[{text:"Ok",addClass:"",promptTrigger:!0,click:function(b,a){b.remove();b.get().trigger("pnotify.confirm",[b,a])}},{text:"Cancel",
-addClass:"",click:function(b){b.remove();b.get().trigger("pnotify.cancel",b)}}]};c.prototype.modules.confirm={container:null,prompt:null,init:function(b,a){this.container=e('<div class="ui-pnotify-action-bar" style="margin-top:5px;clear:both;" />').css("text-align",a.align).appendTo(b.container);a.confirm||a.prompt?this.makeDialog(b,a):this.container.hide()},update:function(b,a){a.confirm?(this.makeDialog(b,a),this.container.show()):this.container.hide().empty()},afterOpen:function(b,a){a.prompt&&
-this.prompt.focus()},makeDialog:function(b,a){var h=!1,l=this,g,d;this.container.empty();a.prompt&&(this.prompt=e("<"+(a.prompt_multi_line?'textarea rows="5"':'input type="text"')+' style="margin-bottom:5px;clear:both;" />').addClass(("undefined"===typeof b.styles.input?"":b.styles.input)+" "+("undefined"===typeof a.prompt_class?"":a.prompt_class)).val(a.prompt_default).appendTo(this.container));for(var m=a.buttons[0]&&a.buttons[0]!==c.prototype.options.confirm.buttons[0],f=0;f<a.buttons.length;f++)if(!(null===
-a.buttons[f]||m&&c.prototype.options.confirm.buttons[f]&&c.prototype.options.confirm.buttons[f]===a.buttons[f])){g=a.buttons[f];h?this.container.append(" "):h=!0;d=e('<button type="button" class="ui-pnotify-action-button" />').addClass(("undefined"===typeof b.styles.btn?"":b.styles.btn)+" "+("undefined"===typeof g.addClass?"":g.addClass)).text(g.text).appendTo(this.container).on("click",function(k){return function(){"function"==typeof k.click&&k.click(b,a.prompt?l.prompt.val():null)}}(g));a.prompt&&
-!a.prompt_multi_line&&g.promptTrigger&&this.prompt.keypress(function(b){return function(a){13==a.keyCode&&b.click()}}(d));b.styles.text&&d.wrapInner('<span class="'+b.styles.text+'"></span>');b.styles.btnhover&&d.hover(function(a){return function(){a.addClass(b.styles.btnhover)}}(d),function(a){return function(){a.removeClass(b.styles.btnhover)}}(d));if(b.styles.btnactive)d.on("mousedown",function(a){return function(){a.addClass(b.styles.btnactive)}}(d)).on("mouseup",function(a){return function(){a.removeClass(b.styles.btnactive)}}(d));
-if(b.styles.btnfocus)d.on("focus",function(a){return function(){a.addClass(b.styles.btnfocus)}}(d)).on("blur",function(a){return function(){a.removeClass(b.styles.btnfocus)}}(d))}}};e.extend(c.styling.jqueryui,{btn:"ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only",btnhover:"ui-state-hover",btnactive:"ui-state-active",btnfocus:"ui-state-focus",input:"",text:"ui-button-text"});e.extend(c.styling.bootstrap2,{btn:"btn",input:""});e.extend(c.styling.bootstrap3,{btn:"btn btn-default",
-input:"form-control"});e.extend(c.styling.fontawesome,{btn:"btn btn-default",input:"form-control"})});

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/external_lib/pnotify/pnotify.buttons.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/external_lib/pnotify/pnotify.buttons.js b/dashboardv2/public/js/external_lib/pnotify/pnotify.buttons.js
new file mode 100644
index 0000000..630cbae
--- /dev/null
+++ b/dashboardv2/public/js/external_lib/pnotify/pnotify.buttons.js
@@ -0,0 +1,8 @@
+(function(d,e){"function"===typeof define&&define.amd?define("pnotify.buttons",["jquery","pnotify"],e):"object"===typeof exports&&"undefined"!==typeof module?module.exports=e(require("jquery"),require("./pnotify")):e(d.jQuery,d.PNotify)})("undefined"!==typeof window?window:this,function(d,e){e.prototype.options.buttons={closer:!0,closer_hover:!0,sticker:!0,sticker_hover:!0,show_on_nonblock:!1,labels:{close:"Close",stick:"Stick",unstick:"Unstick"},classes:{closer:null,pin_up:null,pin_down:null}};e.prototype.modules.buttons=
+{closer:null,sticker:null,init:function(a,b){var c=this;a.elem.on({mouseenter:function(b){!c.options.sticker||a.options.nonblock&&a.options.nonblock.nonblock&&!c.options.show_on_nonblock||c.sticker.trigger("pnotify:buttons:toggleStick").css("visibility","visible");!c.options.closer||a.options.nonblock&&a.options.nonblock.nonblock&&!c.options.show_on_nonblock||c.closer.css("visibility","visible")},mouseleave:function(a){c.options.sticker_hover&&c.sticker.css("visibility","hidden");c.options.closer_hover&&
+c.closer.css("visibility","hidden")}});this.sticker=d("<div />",{"class":"ui-pnotify-sticker","aria-role":"button","aria-pressed":a.options.hide?"false":"true",tabindex:"0",title:a.options.hide?b.labels.stick:b.labels.unstick,css:{cursor:"pointer",visibility:b.sticker_hover?"hidden":"visible"},click:function(){a.options.hide=!a.options.hide;a.options.hide?a.queueRemove():a.cancelRemove();d(this).trigger("pnotify:buttons:toggleStick")}}).bind("pnotify:buttons:toggleStick",function(){var b=null===c.options.classes.pin_up?
+a.styles.pin_up:c.options.classes.pin_up,e=null===c.options.classes.pin_down?a.styles.pin_down:c.options.classes.pin_down;d(this).attr("title",a.options.hide?c.options.labels.stick:c.options.labels.unstick).children().attr("class","").addClass(a.options.hide?b:e).attr("aria-pressed",a.options.hide?"false":"true")}).append("<span />").trigger("pnotify:buttons:toggleStick").prependTo(a.container);(!b.sticker||a.options.nonblock&&a.options.nonblock.nonblock&&!b.show_on_nonblock)&&this.sticker.css("display",
+"none");this.closer=d("<div />",{"class":"ui-pnotify-closer","aria-role":"button",tabindex:"0",title:b.labels.close,css:{cursor:"pointer",visibility:b.closer_hover?"hidden":"visible"},click:function(){a.remove(!1);c.sticker.css("visibility","hidden");c.closer.css("visibility","hidden")}}).append(d("<span />",{"class":null===b.classes.closer?a.styles.closer:b.classes.closer})).prependTo(a.container);(!b.closer||a.options.nonblock&&a.options.nonblock.nonblock&&!b.show_on_nonblock)&&this.closer.css("display",
+"none")},update:function(a,b){!b.closer||a.options.nonblock&&a.options.nonblock.nonblock&&!b.show_on_nonblock?this.closer.css("display","none"):b.closer&&this.closer.css("display","block");!b.sticker||a.options.nonblock&&a.options.nonblock.nonblock&&!b.show_on_nonblock?this.sticker.css("display","none"):b.sticker&&this.sticker.css("display","block");this.sticker.trigger("pnotify:buttons:toggleStick");this.closer.find("span").attr("class","").addClass(null===b.classes.closer?a.styles.closer:b.classes.closer);
+b.sticker_hover?this.sticker.css("visibility","hidden"):a.options.nonblock&&a.options.nonblock.nonblock&&!b.show_on_nonblock||this.sticker.css("visibility","visible");b.closer_hover?this.closer.css("visibility","hidden"):a.options.nonblock&&a.options.nonblock.nonblock&&!b.show_on_nonblock||this.closer.css("visibility","visible")}};d.extend(e.styling.brighttheme,{closer:"brighttheme-icon-closer",pin_up:"brighttheme-icon-sticker",pin_down:"brighttheme-icon-sticker brighttheme-icon-stuck"});d.extend(e.styling.jqueryui,
+{closer:"ui-icon ui-icon-close",pin_up:"ui-icon ui-icon-pin-w",pin_down:"ui-icon ui-icon-pin-s"});d.extend(e.styling.bootstrap2,{closer:"icon-remove",pin_up:"icon-pause",pin_down:"icon-play"});d.extend(e.styling.bootstrap3,{closer:"glyphicon glyphicon-remove",pin_up:"glyphicon glyphicon-pause",pin_down:"glyphicon glyphicon-play"});d.extend(e.styling.fontawesome,{closer:"fa fa-times",pin_up:"fa fa-pause",pin_down:"fa fa-play"})});

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/external_lib/pnotify/pnotify.confirm.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/external_lib/pnotify/pnotify.confirm.js b/dashboardv2/public/js/external_lib/pnotify/pnotify.confirm.js
new file mode 100644
index 0000000..df2f2e3
--- /dev/null
+++ b/dashboardv2/public/js/external_lib/pnotify/pnotify.confirm.js
@@ -0,0 +1,7 @@
+(function(e,c){"function"===typeof define&&define.amd?define("pnotify.confirm",["jquery","pnotify"],c):"object"===typeof exports&&"undefined"!==typeof module?module.exports=c(require("jquery"),require("./pnotify")):c(e.jQuery,e.PNotify)})("undefined"!==typeof window?window:this,function(e,c){c.prototype.options.confirm={confirm:!1,prompt:!1,prompt_class:"",prompt_default:"",prompt_multi_line:!1,align:"right",buttons:[{text:"Ok",addClass:"",promptTrigger:!0,click:function(b,a){b.remove();b.get().trigger("pnotify.confirm",
+[b,a])}},{text:"Cancel",addClass:"",click:function(b){b.remove();b.get().trigger("pnotify.cancel",b)}}]};c.prototype.modules.confirm={container:null,prompt:null,init:function(b,a){this.container=e('<div class="ui-pnotify-action-bar" style="margin-top:5px;clear:both;" />').css("text-align",a.align).appendTo(b.container);a.confirm||a.prompt?this.makeDialog(b,a):this.container.hide()},update:function(b,a){a.confirm?(this.makeDialog(b,a),this.container.show()):this.container.hide().empty()},afterOpen:function(b,
+a){a.prompt&&this.prompt.focus()},makeDialog:function(b,a){var h=!1,l=this,g,d;this.container.empty();a.prompt&&(this.prompt=e("<"+(a.prompt_multi_line?'textarea rows="5"':'input type="text"')+' style="margin-bottom:5px;clear:both;" />').addClass(("undefined"===typeof b.styles.input?"":b.styles.input)+" "+("undefined"===typeof a.prompt_class?"":a.prompt_class)).val(a.prompt_default).appendTo(this.container));for(var m=a.buttons[0]&&a.buttons[0]!==c.prototype.options.confirm.buttons[0],f=0;f<a.buttons.length;f++)if(!(null===
+a.buttons[f]||m&&c.prototype.options.confirm.buttons[f]&&c.prototype.options.confirm.buttons[f]===a.buttons[f])){g=a.buttons[f];h?this.container.append(" "):h=!0;d=e('<button type="button" class="ui-pnotify-action-button" />').addClass(("undefined"===typeof b.styles.btn?"":b.styles.btn)+" "+("undefined"===typeof g.addClass?"":g.addClass)).text(g.text).appendTo(this.container).on("click",function(k){return function(){"function"==typeof k.click&&k.click(b,a.prompt?l.prompt.val():null)}}(g));a.prompt&&
+!a.prompt_multi_line&&g.promptTrigger&&this.prompt.keypress(function(b){return function(a){13==a.keyCode&&b.click()}}(d));b.styles.text&&d.wrapInner('<span class="'+b.styles.text+'"></span>');b.styles.btnhover&&d.hover(function(a){return function(){a.addClass(b.styles.btnhover)}}(d),function(a){return function(){a.removeClass(b.styles.btnhover)}}(d));if(b.styles.btnactive)d.on("mousedown",function(a){return function(){a.addClass(b.styles.btnactive)}}(d)).on("mouseup",function(a){return function(){a.removeClass(b.styles.btnactive)}}(d));
+if(b.styles.btnfocus)d.on("focus",function(a){return function(){a.addClass(b.styles.btnfocus)}}(d)).on("blur",function(a){return function(){a.removeClass(b.styles.btnfocus)}}(d))}}};e.extend(c.styling.jqueryui,{btn:"ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only",btnhover:"ui-state-hover",btnactive:"ui-state-active",btnfocus:"ui-state-focus",input:"",text:"ui-button-text"});e.extend(c.styling.bootstrap2,{btn:"btn",input:""});e.extend(c.styling.bootstrap3,{btn:"btn btn-default",
+input:"form-control"});e.extend(c.styling.fontawesome,{btn:"btn btn-default",input:"form-control"})});

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/external_lib/pnotify/pnotify.custom.min.css
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/external_lib/pnotify/pnotify.custom.min.css b/dashboardv2/public/js/external_lib/pnotify/pnotify.custom.min.css
new file mode 100644
index 0000000..c4c9bf4
--- /dev/null
+++ b/dashboardv2/public/js/external_lib/pnotify/pnotify.custom.min.css
@@ -0,0 +1 @@
+.ui-pnotify{top:36px;right:36px;position:absolute;height:auto;z-index:2}body>.ui-pnotify{position:fixed;z-index:100040}.ui-pnotify-modal-overlay{background-color:rgba(0,0,0,.4);top:0;left:0;position:absolute;height:100%;width:100%;z-index:1}body>.ui-pnotify-modal-overlay{position:fixed;z-index:100039}.ui-pnotify.ui-pnotify-in{display:block!important}.ui-pnotify.ui-pnotify-move{transition:left .5s ease,top .5s ease,right .5s ease,bottom .5s ease}.ui-pnotify.ui-pnotify-fade-slow{transition:opacity .6s linear;opacity:0}.ui-pnotify.ui-pnotify-fade-slow.ui-pnotify.ui-pnotify-move{transition:opacity .6s linear,left .5s ease,top .5s ease,right .5s ease,bottom .5s ease}.ui-pnotify.ui-pnotify-fade-normal{transition:opacity .4s linear;opacity:0}.ui-pnotify.ui-pnotify-fade-normal.ui-pnotify.ui-pnotify-move{transition:opacity .4s linear,left .5s ease,top .5s ease,right .5s ease,bottom .5s ease}.ui-pnotify.ui-pnotify-fade-fast{transition:opacity .2s linear;opacity:0}.ui-pnotify.ui-pnotify-fade-f
 ast.ui-pnotify.ui-pnotify-move{transition:opacity .2s linear,left .5s ease,top .5s ease,right .5s ease,bottom .5s ease}.ui-pnotify.ui-pnotify-fade-in{opacity:1}.ui-pnotify .ui-pnotify-shadow{-webkit-box-shadow:0 6px 28px 0 rgba(0,0,0,.1);-moz-box-shadow:0 6px 28px 0 rgba(0,0,0,.1);box-shadow:0 6px 28px 0 rgba(0,0,0,.1)}.ui-pnotify-container{background-position:0 0;padding:.8em;height:100%;margin:0}.ui-pnotify-container:after{content:" ";visibility:hidden;display:block;height:0;clear:both}.ui-pnotify-container.ui-pnotify-sharp{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.ui-pnotify-title{display:block;margin-bottom:.4em;margin-top:0}.ui-pnotify-text{display:block}.ui-pnotify-icon,.ui-pnotify-icon span{display:block;float:left;margin-right:.2em}.ui-pnotify.stack-bottomleft,.ui-pnotify.stack-topleft{left:25px;right:auto}.ui-pnotify.stack-bottomleft,.ui-pnotify.stack-bottomright{bottom:25px;top:auto}.ui-pnotify.stack-modal{left:50%;right:auto;margin-left:-150px}.brightt
 heme{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.brighttheme.ui-pnotify-container{padding:18px}.brighttheme .ui-pnotify-title{margin-bottom:12px}.brighttheme-notice{background-color:#FFFFA2;border:0 solid #FF0;color:#4F4F00}.brighttheme-info{background-color:#8FCEDD;border:0 solid #0286A5;color:#012831}.brighttheme-success{background-color:#AFF29A;border:0 solid #35DB00;color:#104300}.brighttheme-error{background-color:#FFABA2;background-image:repeating-linear-gradient(135deg,transparent,transparent 35px,rgba(255,255,255,.3) 35px,rgba(255,255,255,.3) 70px);border:0 solid #FF1800;color:#4F0800}.brighttheme-icon-closer,.brighttheme-icon-info,.brighttheme-icon-notice,.brighttheme-icon-sticker,.brighttheme-icon-success{position:relative;width:16px;height:16px;font-size:12px;font-weight:700;line-height:16px;font-family:"Courier New",Courier,monospace;border-radius:50%}.brighttheme-icon-closer:after,.brighttheme-icon-info:after,.brighttheme-icon-notice:after,.brighttheme
 -icon-sticker:after,.brighttheme-icon-success:after{position:absolute;top:0;left:4px}.brighttheme-icon-notice{background-color:#2E2E00;color:#FFFFA2;margin-top:2px}.brighttheme-icon-notice:after{content:"!"}.brighttheme-icon-info{background-color:#012831;color:#8FCEDD;margin-top:2px}.brighttheme-icon-info:after{content:"i"}.brighttheme-icon-success{background-color:#104300;color:#AFF29A;margin-top:2px}.brighttheme-icon-success:after{content:"\002713"}.brighttheme-icon-error{position:relative;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:16px solid #2E0400;font-size:0;line-height:0;color:#FFABA2;margin-top:1px}.brighttheme-icon-error:after{position:absolute;top:1px;left:-4px;font-size:12px;font-weight:700;line-height:16px;font-family:"Courier New",Courier,monospace;content:"!"}.brighttheme-icon-closer,.brighttheme-icon-sticker{display:inline-block}.brighttheme-icon-closer:after{top:-4px;content:"\002715"}.brighttheme-icon-sticker:
 after{top:-5px;content:"\01D1BC";-moz-transform:rotate(-90deg);-webkit-transform:rotate(-90deg);-o-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg)}.brighttheme-icon-sticker.brighttheme-icon-stuck:after{-moz-transform:rotate(180deg);-webkit-transform:rotate(180deg);-o-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.brighttheme .ui-pnotify-action-bar{padding-top:12px}.brighttheme .ui-pnotify-action-bar input,.brighttheme .ui-pnotify-action-bar textarea{display:block;width:100%;margin-bottom:12px!important}.brighttheme .ui-pnotify-action-button{text-transform:uppercase;font-weight:700;padding:4px 8px;border:none;background:0 0}.brighttheme .ui-pnotify-action-button.btn-primary{border:none;border-radius:0}.brighttheme-notice .ui-pnotify-action-button.btn-primary{background-color:#FF0;color:#4F4F00}.brighttheme-info .ui-pnotify-action-button.btn-primary{background-color:#0286A5;color:#012831}.brighttheme-success .ui-pnotify-a
 ction-button.btn-primary{background-color:#35DB00;color:#104300}.brighttheme-error .ui-pnotify-action-button.btn-primary{background-color:#FF1800;color:#4F0800}.ui-pnotify-closer,.ui-pnotify-sticker{float:right;margin-left:.2em}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/external_lib/pnotify/pnotify.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/external_lib/pnotify/pnotify.js b/dashboardv2/public/js/external_lib/pnotify/pnotify.js
new file mode 100644
index 0000000..b3e4cb1
--- /dev/null
+++ b/dashboardv2/public/js/external_lib/pnotify/pnotify.js
@@ -0,0 +1,31 @@
+/*
+PNotify 3.0.0 sciactive.com/pnotify/
+(C) 2015 Hunter Perrin; Google, Inc.
+license Apache-2.0
+*/
+(function(b,k){"function"===typeof define&&define.amd?define("pnotify",["jquery"],function(q){return k(q,b)}):"object"===typeof exports&&"undefined"!==typeof module?module.exports=k(require("jquery"),global||b):b.PNotify=k(b.jQuery,b)})("undefined"!==typeof window?window:this,function(b,k){var q=function(l){var k={dir1:"down",dir2:"left",push:"bottom",spacing1:36,spacing2:36,context:b("body"),modal:!1},g,h,n=b(l),r=function(){h=b("body");d.prototype.options.stack.context=h;n=b(l);n.bind("resize",
+function(){g&&clearTimeout(g);g=setTimeout(function(){d.positionAll(!0)},10)})},s=function(c){var a=b("<div />",{"class":"ui-pnotify-modal-overlay"});a.prependTo(c.context);c.overlay_close&&a.click(function(){d.removeStack(c)});return a},d=function(c){this.parseOptions(c);this.init()};b.extend(d.prototype,{version:"3.0.0",options:{title:!1,title_escape:!1,text:!1,text_escape:!1,styling:"brighttheme",addclass:"",cornerclass:"",auto_display:!0,width:"300px",min_height:"16px",type:"notice",icon:!0,animation:"fade",
+animate_speed:"normal",shadow:!0,hide:!0,delay:8E3,mouse_reset:!0,remove:!0,insert_brs:!0,destroy:!0,stack:k},modules:{},runModules:function(c,a){var p,b;for(b in this.modules)p="object"===typeof a&&b in a?a[b]:a,"function"===typeof this.modules[b][c]&&(this.modules[b].notice=this,this.modules[b].options="object"===typeof this.options[b]?this.options[b]:{},this.modules[b][c](this,"object"===typeof this.options[b]?this.options[b]:{},p))},state:"initializing",timer:null,animTimer:null,styles:null,elem:null,
+container:null,title_container:null,text_container:null,animating:!1,timerHide:!1,init:function(){var c=this;this.modules={};b.extend(!0,this.modules,d.prototype.modules);this.styles="object"===typeof this.options.styling?this.options.styling:d.styling[this.options.styling];this.elem=b("<div />",{"class":"ui-pnotify "+this.options.addclass,css:{display:"none"},"aria-live":"assertive","aria-role":"alertdialog",mouseenter:function(a){if(c.options.mouse_reset&&"out"===c.animating){if(!c.timerHide)return;
+c.cancelRemove()}c.options.hide&&c.options.mouse_reset&&c.cancelRemove()},mouseleave:function(a){c.options.hide&&c.options.mouse_reset&&"out"!==c.animating&&c.queueRemove();d.positionAll()}});"fade"===this.options.animation&&this.elem.addClass("ui-pnotify-fade-"+this.options.animate_speed);this.container=b("<div />",{"class":this.styles.container+" ui-pnotify-container "+("error"===this.options.type?this.styles.error:"info"===this.options.type?this.styles.info:"success"===this.options.type?this.styles.success:
+this.styles.notice),role:"alert"}).appendTo(this.elem);""!==this.options.cornerclass&&this.container.removeClass("ui-corner-all").addClass(this.options.cornerclass);this.options.shadow&&this.container.addClass("ui-pnotify-shadow");!1!==this.options.icon&&b("<div />",{"class":"ui-pnotify-icon"}).append(b("<span />",{"class":!0===this.options.icon?"error"===this.options.type?this.styles.error_icon:"info"===this.options.type?this.styles.info_icon:"success"===this.options.type?this.styles.success_icon:
+this.styles.notice_icon:this.options.icon})).prependTo(this.container);this.title_container=b("<h4 />",{"class":"ui-pnotify-title"}).appendTo(this.container);!1===this.options.title?this.title_container.hide():this.options.title_escape?this.title_container.text(this.options.title):this.title_container.html(this.options.title);this.text_container=b("<div />",{"class":"ui-pnotify-text","aria-role":"alert"}).appendTo(this.container);!1===this.options.text?this.text_container.hide():this.options.text_escape?
+this.text_container.text(this.options.text):this.text_container.html(this.options.insert_brs?String(this.options.text).replace(/\n/g,"<br />"):this.options.text);"string"===typeof this.options.width&&this.elem.css("width",this.options.width);"string"===typeof this.options.min_height&&this.container.css("min-height",this.options.min_height);d.notices="top"===this.options.stack.push?b.merge([this],d.notices):b.merge(d.notices,[this]);"top"===this.options.stack.push&&this.queuePosition(!1,1);this.options.stack.animation=
+!1;this.runModules("init");this.options.auto_display&&this.open();return this},update:function(c){var a=this.options;this.parseOptions(a,c);this.elem.removeClass("ui-pnotify-fade-slow ui-pnotify-fade-normal ui-pnotify-fade-fast");"fade"===this.options.animation&&this.elem.addClass("ui-pnotify-fade-"+this.options.animate_speed);this.options.cornerclass!==a.cornerclass&&this.container.removeClass("ui-corner-all "+a.cornerclass).addClass(this.options.cornerclass);this.options.shadow!==a.shadow&&(this.options.shadow?
+this.container.addClass("ui-pnotify-shadow"):this.container.removeClass("ui-pnotify-shadow"));!1===this.options.addclass?this.elem.removeClass(a.addclass):this.options.addclass!==a.addclass&&this.elem.removeClass(a.addclass).addClass(this.options.addclass);!1===this.options.title?this.title_container.slideUp("fast"):this.options.title!==a.title&&(this.options.title_escape?this.title_container.text(this.options.title):this.title_container.html(this.options.title),!1===a.title&&this.title_container.slideDown(200));
+!1===this.options.text?this.text_container.slideUp("fast"):this.options.text!==a.text&&(this.options.text_escape?this.text_container.text(this.options.text):this.text_container.html(this.options.insert_brs?String(this.options.text).replace(/\n/g,"<br />"):this.options.text),!1===a.text&&this.text_container.slideDown(200));this.options.type!==a.type&&this.container.removeClass(this.styles.error+" "+this.styles.notice+" "+this.styles.success+" "+this.styles.info).addClass("error"===this.options.type?
+this.styles.error:"info"===this.options.type?this.styles.info:"success"===this.options.type?this.styles.success:this.styles.notice);if(this.options.icon!==a.icon||!0===this.options.icon&&this.options.type!==a.type)this.container.find("div.ui-pnotify-icon").remove(),!1!==this.options.icon&&b("<div />",{"class":"ui-pnotify-icon"}).append(b("<span />",{"class":!0===this.options.icon?"error"===this.options.type?this.styles.error_icon:"info"===this.options.type?this.styles.info_icon:"success"===this.options.type?
+this.styles.success_icon:this.styles.notice_icon:this.options.icon})).prependTo(this.container);this.options.width!==a.width&&this.elem.animate({width:this.options.width});this.options.min_height!==a.min_height&&this.container.animate({minHeight:this.options.min_height});this.options.hide?a.hide||this.queueRemove():this.cancelRemove();this.queuePosition(!0);this.runModules("update",a);return this},open:function(){this.state="opening";this.runModules("beforeOpen");var c=this;this.elem.parent().length||
+this.elem.appendTo(this.options.stack.context?this.options.stack.context:h);"top"!==this.options.stack.push&&this.position(!0);this.animateIn(function(){c.queuePosition(!0);c.options.hide&&c.queueRemove();c.state="open";c.runModules("afterOpen")});return this},remove:function(c){this.state="closing";this.timerHide=!!c;this.runModules("beforeClose");var a=this;this.timer&&(l.clearTimeout(this.timer),this.timer=null);this.animateOut(function(){a.state="closed";a.runModules("afterClose");a.queuePosition(!0);
+a.options.remove&&a.elem.detach();a.runModules("beforeDestroy");if(a.options.destroy&&null!==d.notices){var c=b.inArray(a,d.notices);-1!==c&&d.notices.splice(c,1)}a.runModules("afterDestroy")});return this},get:function(){return this.elem},parseOptions:function(c,a){this.options=b.extend(!0,{},d.prototype.options);this.options.stack=d.prototype.options.stack;for(var p=[c,a],m,f=0;f<p.length;f++){m=p[f];if("undefined"===typeof m)break;if("object"!==typeof m)this.options.text=m;else for(var e in m)this.modules[e]?
+b.extend(!0,this.options[e],m[e]):this.options[e]=m[e]}},animateIn:function(c){this.animating="in";var a=this;c=function(){a.animTimer&&clearTimeout(a.animTimer);"in"===a.animating&&(a.elem.is(":visible")?(this&&this.call(),a.animating=!1):a.animTimer=setTimeout(c,40))}.bind(c);"fade"===this.options.animation?(this.elem.one("webkitTransitionEnd mozTransitionEnd MSTransitionEnd oTransitionEnd transitionend",c).addClass("ui-pnotify-in"),this.elem.css("opacity"),this.elem.addClass("ui-pnotify-fade-in"),
+this.animTimer=setTimeout(c,650)):(this.elem.addClass("ui-pnotify-in"),c())},animateOut:function(c){this.animating="out";var a=this;c=function(){a.animTimer&&clearTimeout(a.animTimer);"out"===a.animating&&("0"!=a.elem.css("opacity")&&a.elem.is(":visible")?a.animTimer=setTimeout(c,40):(a.elem.removeClass("ui-pnotify-in"),this&&this.call(),a.animating=!1))}.bind(c);"fade"===this.options.animation?(this.elem.one("webkitTransitionEnd mozTransitionEnd MSTransitionEnd oTransitionEnd transitionend",c).removeClass("ui-pnotify-fade-in"),
+this.animTimer=setTimeout(c,650)):(this.elem.removeClass("ui-pnotify-in"),c())},position:function(c){var a=this.options.stack,b=this.elem;"undefined"===typeof a.context&&(a.context=h);if(a){"number"!==typeof a.nextpos1&&(a.nextpos1=a.firstpos1);"number"!==typeof a.nextpos2&&(a.nextpos2=a.firstpos2);"number"!==typeof a.addpos2&&(a.addpos2=0);var d=!b.hasClass("ui-pnotify-in");if(!d||c){a.modal&&(a.overlay?a.overlay.show():a.overlay=s(a));b.addClass("ui-pnotify-move");var f;switch(a.dir1){case "down":f=
+"top";break;case "up":f="bottom";break;case "left":f="right";break;case "right":f="left"}c=parseInt(b.css(f).replace(/(?:\..*|[^0-9.])/g,""));isNaN(c)&&(c=0);"undefined"!==typeof a.firstpos1||d||(a.firstpos1=c,a.nextpos1=a.firstpos1);var e;switch(a.dir2){case "down":e="top";break;case "up":e="bottom";break;case "left":e="right";break;case "right":e="left"}c=parseInt(b.css(e).replace(/(?:\..*|[^0-9.])/g,""));isNaN(c)&&(c=0);"undefined"!==typeof a.firstpos2||d||(a.firstpos2=c,a.nextpos2=a.firstpos2);
+if("down"===a.dir1&&a.nextpos1+b.height()>(a.context.is(h)?n.height():a.context.prop("scrollHeight"))||"up"===a.dir1&&a.nextpos1+b.height()>(a.context.is(h)?n.height():a.context.prop("scrollHeight"))||"left"===a.dir1&&a.nextpos1+b.width()>(a.context.is(h)?n.width():a.context.prop("scrollWidth"))||"right"===a.dir1&&a.nextpos1+b.width()>(a.context.is(h)?n.width():a.context.prop("scrollWidth")))a.nextpos1=a.firstpos1,a.nextpos2+=a.addpos2+("undefined"===typeof a.spacing2?25:a.spacing2),a.addpos2=0;"number"===
+typeof a.nextpos2&&(a.animation?b.css(e,a.nextpos2+"px"):(b.removeClass("ui-pnotify-move"),b.css(e,a.nextpos2+"px"),b.css(e),b.addClass("ui-pnotify-move")));switch(a.dir2){case "down":case "up":b.outerHeight(!0)>a.addpos2&&(a.addpos2=b.height());break;case "left":case "right":b.outerWidth(!0)>a.addpos2&&(a.addpos2=b.width())}"number"===typeof a.nextpos1&&(a.animation?b.css(f,a.nextpos1+"px"):(b.removeClass("ui-pnotify-move"),b.css(f,a.nextpos1+"px"),b.css(f),b.addClass("ui-pnotify-move")));switch(a.dir1){case "down":case "up":a.nextpos1+=
+b.height()+("undefined"===typeof a.spacing1?25:a.spacing1);break;case "left":case "right":a.nextpos1+=b.width()+("undefined"===typeof a.spacing1?25:a.spacing1)}}return this}},queuePosition:function(b,a){g&&clearTimeout(g);a||(a=10);g=setTimeout(function(){d.positionAll(b)},a);return this},cancelRemove:function(){this.timer&&l.clearTimeout(this.timer);this.animTimer&&l.clearTimeout(this.animTimer);"closing"===this.state&&(this.state="open",this.animating=!1,this.elem.addClass("ui-pnotify-in"),"fade"===
+this.options.animation&&this.elem.addClass("ui-pnotify-fade-in"));return this},queueRemove:function(){var b=this;this.cancelRemove();this.timer=l.setTimeout(function(){b.remove(!0)},isNaN(this.options.delay)?0:this.options.delay);return this}});b.extend(d,{notices:[],reload:q,removeAll:function(){b.each(d.notices,function(){this.remove&&this.remove(!1)})},removeStack:function(c){b.each(d.notices,function(){this.remove&&this.options.stack===c&&this.remove(!1)})},positionAll:function(c){g&&clearTimeout(g);
+g=null;if(d.notices&&d.notices.length)b.each(d.notices,function(){var a=this.options.stack;a&&(a.overlay&&a.overlay.hide(),a.nextpos1=a.firstpos1,a.nextpos2=a.firstpos2,a.addpos2=0,a.animation=c)}),b.each(d.notices,function(){this.position()});else{var a=d.prototype.options.stack;a&&(delete a.nextpos1,delete a.nextpos2)}},styling:{brighttheme:{container:"brighttheme",notice:"brighttheme-notice",notice_icon:"brighttheme-icon-notice",info:"brighttheme-info",info_icon:"brighttheme-icon-info",success:"brighttheme-success",
+success_icon:"brighttheme-icon-success",error:"brighttheme-error",error_icon:"brighttheme-icon-error"},jqueryui:{container:"ui-widget ui-widget-content ui-corner-all",notice:"ui-state-highlight",notice_icon:"ui-icon ui-icon-info",info:"",info_icon:"ui-icon ui-icon-info",success:"ui-state-default",success_icon:"ui-icon ui-icon-circle-check",error:"ui-state-error",error_icon:"ui-icon ui-icon-alert"},bootstrap3:{container:"alert",notice:"alert-warning",notice_icon:"glyphicon glyphicon-exclamation-sign",
+info:"alert-info",info_icon:"glyphicon glyphicon-info-sign",success:"alert-success",success_icon:"glyphicon glyphicon-ok-sign",error:"alert-danger",error_icon:"glyphicon glyphicon-warning-sign"}}});d.styling.fontawesome=b.extend({},d.styling.bootstrap3);b.extend(d.styling.fontawesome,{notice_icon:"fa fa-exclamation-circle",info_icon:"fa fa-info",success_icon:"fa fa-check",error_icon:"fa fa-warning"});l.document.body?r():b(r);return d};return q(k)});

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/main.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/main.js b/dashboardv2/public/js/main.js
index 3b7f2b2..2ddf1aa 100644
--- a/dashboardv2/public/js/main.js
+++ b/dashboardv2/public/js/main.js
@@ -139,7 +139,9 @@ require.config({
         'moment': 'libs/moment/js/moment.min',
         'jquery-ui': 'external_lib/jquery-ui/jquery-ui.min',
         'datetimepicker': 'external_lib/datetimepicker/bootstrap-datetimepicker',
-        'pnotify': 'external_lib/pnotify.custom.min',
+        'pnotify': 'external_lib/pnotify/pnotify',
+        'pnotify.buttons': 'external_lib/pnotify/pnotify.buttons',
+        'pnotify.confirm': 'external_lib/pnotify/pnotify.confirm',
         'jquery-placeholder': 'libs/jquery-placeholder/js/jquery.placeholder',
         'platform': 'libs/platform/platform'
     },

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/models/VEntity.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/models/VEntity.js b/dashboardv2/public/js/models/VEntity.js
index ce86c24..6f44a88 100644
--- a/dashboardv2/public/js/models/VEntity.js
+++ b/dashboardv2/public/js/models/VEntity.js
@@ -52,8 +52,8 @@ define(['require',
 
             return this.constructor.nonCrudOperation.call(this, url, 'GET', options);
         },
-        saveEntity: function(token, options) {
-            var url = UrlLinks.entitiesTraitsApiUrl(token);
+        saveTraitsEntity: function(options) {
+            var url = UrlLinks.entitiesTraitsApiUrl();
             options = _.extend({
                 contentType: 'application/json',
                 dataType: 'json'

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/modules/atlasLogin.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/modules/atlasLogin.js b/dashboardv2/public/js/modules/atlasLogin.js
index 0fec3e4..dffe4e0 100644
--- a/dashboardv2/public/js/modules/atlasLogin.js
+++ b/dashboardv2/public/js/modules/atlasLogin.js
@@ -19,110 +19,113 @@
 
 //Define indexOf for IE
 if (!Array.indexOf) {
-	Array.prototype.indexOf = function(obj, start) {
-		for ( var i = (start || 0); i < this.length; i++) {
-			if (this[i] == obj) {
-				return i;
-			}
-		}
-		return -1;
-	};
+    Array.prototype.indexOf = function(obj, start) {
+        for (var i = (start || 0); i < this.length; i++) {
+            if (this[i] == obj) {
+                return i;
+            }
+        }
+        return -1;
+    };
 }
 
 
 function doLogin() {
 
-	var userName = $('#username').val().trim();
-	var passwd = $('#password').val().trim();
+    var userName = $('#username').val().trim();
+    var passwd = $('#password').val().trim();
 
-	if (userName === '' || passwd === '') {
-		$('#errorBox').show();
-		$('#signInLoading').hide();
-		$('#signIn').removeAttr('disabled');
-		$('#errorBox .errorMsg').text("The username or password you entered is blank..");
-		return false;
-	}
+    if (userName === '' || passwd === '') {
+        $('#errorBox').show();
+        $('#signInLoading').hide();
+        $('#signIn').removeAttr('disabled');
+        $('#errorBox .errorMsg').text("The username or password you entered is blank..");
+        return false;
+    }
 
-	var baseUrl = getBaseUrl();
-	if (baseUrl.lastIndexOf('/') != (baseUrl.length - 1)) {
-		if (baseUrl) {
-			baseUrl = baseUrl + '/';
-		} else {
-			baseUrl = '/';
-		}
-	}
-	var url = baseUrl + 'j_spring_security_check';
+    var baseUrl = getBaseUrl();
+    if (baseUrl.lastIndexOf('/') != (baseUrl.length - 1)) {
+        if (baseUrl) {
+            baseUrl = baseUrl + '/';
+        } else {
+            baseUrl = '/';
+        }
+    }
+    var url = baseUrl + 'j_spring_security_check';
 
-	$.ajax({
-		data : {
-			j_username : userName,
-			j_password : passwd
-		},
-		url : url,
-		type : 'POST',
-		headers : {
-			"cache-control" : "no-cache"
-		},
-		success : function() {
-			if(location.hash.length > 2)
-				window.location.replace('index.html'+location.hash);
-			else
-				window.location.replace('index.html');
-		},
-		error : function(jqXHR, textStatus, err ) {
-			$('#signIn').removeAttr('disabled');
-			$('#signInLoading').css("visibility", "hidden");
+    $.ajax({
+        data: {
+            j_username: userName,
+            j_password: passwd
+        },
+        url: url,
+        type: 'POST',
+        headers: {
+            "cache-control": "no-cache"
+        },
+        success: function() {
+            if (location.hash.length > 2)
+                window.location.replace('index.html' + location.hash);
+            else
+                window.location.replace('index.html');
+        },
+        error: function(jqXHR, textStatus, err) {
+            $('#signIn').removeAttr('disabled');
+            $('#signInLoading').css("visibility", "hidden");
 
-			if(jqXHR.status && jqXHR.status == 412){
-				$('#errorBox').hide();
-				$('#errorBoxUnsynced').show();
-			} else {
-				var resp = JSON.parse(jqXHR.responseText);
+            if (jqXHR.status && jqXHR.status == 412) {
+                $('#errorBox').hide();
+                $('#errorBoxUnsynced').show();
+            } else {
+                try {
+                    var resp = JSON.parse(jqXHR.responseText);
 
-                if(resp.msgDesc.startsWith("Username not found") || resp.msgDesc.startsWith("Wrong password")){
-                    $('#errorBox .errorMsg').text("Invalid User credentials. Please try again.");
-                }else if(resp.msgDesc.startsWith("User role credentials is not set properly")){
-                    $('#errorBox .errorMsg').text("User role or credentials is not set properly");
-                }else{
-                    $('#errorBox .errorMsg').text("Error while authentication");
+                    if (resp.msgDesc.startsWith("Username not found") || resp.msgDesc.startsWith("Wrong password")) {
+                        $('#errorBox .errorMsg').text("Invalid User credentials. Please try again.");
+                    } else if (resp.msgDesc.startsWith("User role credentials is not set properly")) {
+                        $('#errorBox .errorMsg').text("User role or credentials is not set properly");
+                    } else {
+                        $('#errorBox .errorMsg').text("Error while authentication");
+                    }
+                } catch (err) {
+                    $('#errorBox .errorMsg').text("Something went wrong");
                 }
-
-				$('#errorBox').show();
-				$('#errorBoxUnsynced').hide();
-			}
-		}
-	});
+                $('#errorBox').show();
+                $('#errorBoxUnsynced').hide();
+            }
+        }
+    });
 }
-function getBaseUrl(){
-	if(!window.location.origin){
-		window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
-	}
-	return window.location.origin
-	+ window.location.pathname.substring(window.location.pathname
-			.indexOf('/', 2) + 1, 0);
+
+function getBaseUrl() {
+    if (!window.location.origin) {
+        window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port : '');
+    }
+    return window.location.origin + window.location.pathname.substring(window.location.pathname
+        .indexOf('/', 2) + 1, 0);
 }
 $(function() {
-// register handlers
-	$('#signIn').on('click', function() {
-		$('#signIn').attr('disabled',true);
-		$('#signInLoading').css("visibility", "visible");
-		doLogin();
-		return false;
-	});
-	$('#loginForm').each(function() {
-		$('input').keypress(function(e) {
-			// Enter pressed?
-			if (e.which == 10 || e.which == 13) {
-				doLogin();
-			}
-		});
-	});
-	
-	$('#loginForm  li[class^=control-group] > input').on('change',function(e){
-		if(e.target.value === ''){
-			$(e.target).parent().addClass('error');
-		}else{
-			$(e.target).parent().removeClass('error');
-		}
-	});
+    // register handlers
+    $('#signIn').on('click', function() {
+        $('#signIn').attr('disabled', true);
+        $('#signInLoading').css("visibility", "visible");
+        doLogin();
+        return false;
+    });
+    $('#loginForm').each(function() {
+        $('input').keypress(function(e) {
+            // Enter pressed?
+            if (e.which == 10 || e.which == 13) {
+                doLogin();
+            }
+        });
+    });
+
+    $('#loginForm  li[class^=control-group] > input').on('change', function(e) {
+        if (e.target.value === '') {
+            $(e.target).parent().addClass('error');
+        } else {
+            $(e.target).parent().removeClass('error');
+        }
+    });
 });

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/utils/CommonViewFunction.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/CommonViewFunction.js b/dashboardv2/public/js/utils/CommonViewFunction.js
index c0203ea..e15759a 100644
--- a/dashboardv2/public/js/utils/CommonViewFunction.js
+++ b/dashboardv2/public/js/utils/CommonViewFunction.js
@@ -285,28 +285,28 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
             });
         }
     }
-    CommonViewFunction.termTableBreadcrumbMaker = function(model) {
-        if (!model) {
+    CommonViewFunction.termTableBreadcrumbMaker = function(obj) {
+        if (!obj) {
             return "";
         }
-        var traits = model.get('$traits$'),
+        var traits = obj.classificationNames,
             url = "",
             deleteHtml = "",
             html = "",
-            id = model.get('$id$').id || model.get('$id$'),
-            terms = [];
-        _.keys(traits).map(function(key) {
-            if (traits[key]) {
-                var tagName = Utils.checkTagOrTerm(traits[key]);
-            }
-            if (tagName.term) {
-                terms.push({
-                    deleteHtml: '<a class="pull-left" title="Remove Term"><i class="fa fa-trash" data-id="tagClick" data-type="term" data-assetname="' + _.escape(model.get("name")) + '" data-name="' + tagName.fullName + '" data-guid="' + (model.get('$id$').id || model.get('$id$')) + '" ></i></a>',
-                    url: _.unescape(tagName.fullName).split(".").join("/"),
-                    name: tagName.fullName
-                });
-            }
-        });
+            id = obj.guid,
+            terms = [],
+            entityName = (_.escape(obj.attributes && obj.attributes.name ? obj.attributes.name : null) || _.escape(obj.displayText) || obj.guid);
+        if (traits) {
+            traits.map(function(term) {
+                if (term.split(".").length > 1) {
+                    terms.push({
+                        deleteHtml: '<a class="pull-left" title="Remove Term"><i class="fa fa-trash" data-id="tagClick" data-type="term" data-assetname="' + entityName + '" data-name="' + term + '" data-guid="' + obj.guid + '" ></i></a>',
+                        url: _.unescape(term).split(".").join("/"),
+                        name: term
+                    });
+                }
+            });
+        }
         _.each(terms, function(obj, i) {
             var className = "";
             if (i >= 1) {
@@ -318,10 +318,12 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
         if (terms.length > 1) {
             html += '<div><a  href="javascript:void(0)" data-id="showMoreLessTerm" class="inputTag inputTagGreen"><span>Show More </span><i class="fa fa-angle-right"></i></a></div>'
         }
-        if (model.get('$id$')) {
-            html += '<div><a href="javascript:void(0)" class="inputAssignTag" data-id="addTerm" data-guid="' + (model.get('$id$').id || model.get('$id$')) + '"><i class="fa fa-folder-o"></i>' + " " + 'Assign Term</a></div>'
-        } else {
-            html += '<div><a href="javascript:void(0)" class="inputAssignTag" data-id="addTerm"><i class="fa fa-folder-o"></i>' + " " + 'Assign Term</a></div>'
+        if (!Enums.entityStateReadOnly[obj.status]) {
+            if (obj.guid) {
+                html += '<div><a href="javascript:void(0)" class="inputAssignTag" data-id="addTerm" data-guid="' + (obj.guid) + '"><i class="fa fa-folder-o"></i>' + " " + 'Assign Term</a></div>'
+            } else {
+                html += '<div><a href="javascript:void(0)" class="inputAssignTag" data-id="addTerm"><i class="fa fa-folder-o"></i>' + " " + 'Assign Term</a></div>'
+            }
         }
         return {
             html: '<div class="termTableBreadcrumb" dataterm-id="' + id + '">' + html + '</div>',
@@ -329,30 +331,32 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
         }
 
     }
-    CommonViewFunction.tagForTable = function(model) {
-        var traits = model.get('$traits$'),
+    CommonViewFunction.tagForTable = function(obj) {
+        var traits = obj.classificationNames,
             atags = "",
             addTag = "",
             popTag = "",
-            count = 0;
-        _.keys(model.get('$traits$')).map(function(key) {
-            if (traits[key]) {
-                var tagName = Utils.checkTagOrTerm(traits[key]);
-            }
-            var className = "inputTag";
-            if (tagName.tag) {
-                if (count >= 1) {
-                    popTag += '<a class="' + className + '" data-id="tagClick"><span class="inputValue">' + tagName.fullName + '</span><i class="fa fa-times" data-id="delete"  data-assetname="' + model.get("name") + '"data-name="' + tagName.fullName + '" data-type="tag" data-guid="' + (model.get('$id$').id || model.get('$id$')) + '" ></i></a>';
-                } else {
-                    atags += '<a class="' + className + '" data-id="tagClick"><span class="inputValue">' + tagName.fullName + '</span><i class="fa fa-times" data-id="delete" data-assetname="' + model.get("name") + '" data-name="' + tagName.fullName + '"  data-type="tag" data-guid="' + (model.get('$id$').id || model.get('$id$')) + '" ></i></a>';
+            count = 0,
+            entityName = (_.escape(obj.attributes && obj.attributes.name ? obj.attributes.name : null) || _.escape(obj.displayText) || obj.guid);
+        if (traits) {
+            traits.map(function(tag) {
+                if (tag.split(".").length === 1) {
+                    var className = "inputTag";
+                    if (count >= 1) {
+                        popTag += '<a class="' + className + '" data-id="tagClick"><span class="inputValue">' + tag + '</span><i class="fa fa-times" data-id="delete"  data-assetname="' + entityName + '"data-name="' + tag + '" data-type="tag" data-guid="' + obj.guid + '" ></i></a>';
+                    } else {
+                        atags += '<a class="' + className + '" data-id="tagClick"><span class="inputValue">' + tag + '</span><i class="fa fa-times" data-id="delete" data-assetname="' + entityName + '" data-name="' + tag + '"  data-type="tag" data-guid="' + obj.guid + '" ></i></a>';
+                    }
+                    ++count;
                 }
-                ++count;
+            });
+        }
+        if (!Enums.entityStateReadOnly[obj.status]) {
+            if (obj.guid) {
+                addTag += '<a href="javascript:void(0)" data-id="addTag" class="inputTagAdd assignTag" data-guid="' + obj.guid + '" ><i class="fa fa-plus"></i></a>';
+            } else {
+                addTag += '<a href="javascript:void(0)" data-id="addTag" class="inputTagAdd assignTag"><i style="right:0" class="fa fa-plus"></i></a>';
             }
-        });
-        if (model.get('$id$')) {
-            addTag += '<a href="javascript:void(0)" data-id="addTag" class="inputTagAdd assignTag" data-guid="' + (model.get('$id$').id || model.get('$id$')) + '" ><i class="fa fa-plus"></i></a>';
-        } else {
-            addTag += '<a href="javascript:void(0)" data-id="addTag" class="inputTagAdd assignTag"><i style="right:0" class="fa fa-plus"></i></a>';
         }
         if (count > 1) {
             addTag += '<div data-id="showMoreLess" class="inputTagAdd assignTag tagDetailPopover"><i class="fa fa-ellipsis-h" aria-hidden="true"></i></div>'

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/utils/Messages.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/Messages.js b/dashboardv2/public/js/utils/Messages.js
index 4bf404e..eab7d14 100644
--- a/dashboardv2/public/js/utils/Messages.js
+++ b/dashboardv2/public/js/utils/Messages.js
@@ -35,7 +35,7 @@ define(['require'], function(require) {
         updateTagDescriptionMessage: "Tag description is updated successfully",
         updateTermDescriptionMessage: "Term description is updated successfully",
         editSuccessMessage: " has been updated successfully",
-        assignDeletedEntity: " entity is deleted, tag cannot be assigned"
+        assignDeletedEntity: " is deleted, tag cannot be assigned"
     };
     return Messages;
 });

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/utils/UrlLinks.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/UrlLinks.js b/dashboardv2/public/js/utils/UrlLinks.js
index 901de5a..a84ce47 100644
--- a/dashboardv2/public/js/utils/UrlLinks.js
+++ b/dashboardv2/public/js/utils/UrlLinks.js
@@ -47,7 +47,13 @@ define(['require', 'utils/Enums'], function(require, Enums) {
             }
         },
         entitiesTraitsApiUrl: function(token) {
-            return this.baseUrlV2 + '/entity/guid/' + token + "/classifications"; //this.entitiesApiUrl();
+            if (token) {
+                return this.baseUrlV2 + '/entity/guid/' + token + '/classifications';
+            } else {
+                // For Multiple Assignment
+                return this.baseUrlV2 + '/entities/classification';
+            }
+
         },
         entityCollectionaudit: function(guid) {
             return this.baseUrl + '/entities/' + guid + '/audit';
@@ -82,7 +88,7 @@ define(['require', 'utils/Enums'], function(require, Enums) {
             }
         },
         searchApiUrl: function(searchtype) {
-            var searchUrl = this.baseUrl + '/discovery/search';
+            var searchUrl = this.baseUrlV2 + '/search';
             if (searchtype) {
                 return searchUrl + '/' + searchtype;
             } else {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/utils/Utils.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/Utils.js b/dashboardv2/public/js/utils/Utils.js
index 259ea2c..cbe7a2b 100644
--- a/dashboardv2/public/js/utils/Utils.js
+++ b/dashboardv2/public/js/utils/Utils.js
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 
-define(['require', 'utils/Globals', 'pnotify', 'utils/Messages'], function(require, Globals, pnotify, Messages) {
+define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'pnotify.buttons', 'pnotify.confirm'], function(require, Globals, pnotify, Messages) {
     'use strict';
 
     var Utils = {};
@@ -49,35 +49,60 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages'], function(requi
     };
 
     var notify = function(options) {
-        new pnotify(_.extend({ icon: true, hide: true, delay: 3000, remove: true }, options));
+        return new pnotify(_.extend({ icon: true, hide: true, delay: 3000, remove: true }, options));
     }
     Utils.notifyInfo = function(options) {
         notify({
             type: "info",
-            text: _.escape(options.content) || "Info message."
+            text: (options.html ? options.content : _.escape(options.content)) || "Info message."
         });
     };
 
     Utils.notifyWarn = function(options) {
         notify({
             type: "notice",
-            text: _.escape(options.content) || "Info message."
+            text: (options.html ? options.content : _.escape(options.content)) || "Info message."
         });
     };
 
     Utils.notifyError = function(options) {
         notify({
             type: "error",
-            text: _.escape(options.content) || "Error occurred."
+            text: (options.html ? options.content : _.escape(options.content)) || "Error occurred."
         });
     };
 
     Utils.notifySuccess = function(options) {
         notify({
             type: "success",
-            text: _.escape(options.content) || "Error occurred."
+            text: (options.html ? options.content : _.escape(options.content)) || "Error occurred."
         });
     };
+
+    Utils.notifyConfirm = function(options) {
+        notify(_.extend({
+            title: 'Confirmation',
+            hide: false,
+            confirm: {
+                confirm: true
+            },
+            buttons: {
+                closer: false,
+                sticker: false
+            },
+            history: {
+                history: false
+            }
+        }, options)).get().on('pnotify.confirm', function() {
+            if (options.ok) {
+                options.ok();
+            }
+        }).on('pnotify.cancel', function() {
+            if (options.cancel) {
+                options.cancel();
+            }
+        });
+    }
     Utils.defaultErrorHandler = function(model, error) {
         if (error && error.status) {
             if (error.status == 401) {
@@ -87,11 +112,13 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages'], function(requi
             } else if (error.status == 403) {
                 var message = "You are not authorized";
                 if (error.statusText) {
-                    message = JSON.parse(error.statusText).AuthorizationError;
+                    try {
+                        message = JSON.parse(error.statusText).AuthorizationError;
+                    } catch (err) {}
+                    Utils.notifyError({
+                        content: message
+                    });
                 }
-                Utils.notifyError({
-                    content: message
-                });
             } else if (error.status == "0" && error.statusText != "abort") {
                 var diffTime = (new Date().getTime() - prevNetworkErrorTime);
                 if (diffTime > 3000) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c9c26d74/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
index 3f197cf..c959229 100644
--- a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
+++ b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
@@ -129,6 +129,9 @@ define(['require',
                             if (!this.name && collectionJSON.attributes.qualifiedName) {
                                 this.name = collectionJSON.attributes.qualifiedName;
                             }
+                            if (!this.name && collectionJSON.displayText) {
+                                this.name = collectionJSON.displayText;
+                            }
                             if (this.name && collectionJSON.typeName) {
                                 this.name = this.name + ' (' + collectionJSON.typeName + ')';
                             }
@@ -162,7 +165,7 @@ define(['require',
                             this.addTagToTerms([]);
                         }
                     }
-                    Utils.hideTitleLoader(this.$('.page-title .fontLoader'), this.$('.entityDetail'));
+                    this.hideLoader();
                     this.auditVent.trigger("reset:collection");
                     this.renderEntityDetailTableLayoutView();
                     this.renderTagTableLayoutView(tagGuid);
@@ -234,12 +237,12 @@ define(['require',
                     termData = "";
 
                 _.each(tagObject, function(val) {
-                    var isTerm = Utils.checkTagOrTerm(val);
-                    if (isTerm.tag) {
-                        tagData += '<span class="inputTag" data-id="tagClick"><span class="inputValue">' + isTerm.fullName + '</span><i class="fa fa-close" data-id="deleteTag" data-type="tag"></i></span>';
+                    //var isTerm = Utils.checkTagOrTerm(val);
+                    if (val.typeName && val.typeName.split('.').length === 1) {
+                        tagData += '<span class="inputTag" data-id="tagClick"><span class="inputValue">' + val.typeName + '</span><i class="fa fa-close" data-id="deleteTag" data-type="tag"></i></span>';
                     }
-                    if (isTerm.term) {
-                        termData += '<span class="inputTag term" data-id="tagClick" data-href="' + isTerm.fullName + '"><span class="inputValue">' + isTerm.fullName + '</span><i class="fa fa-close" data-id="deleteTag" data-type="term"></i></span>';
+                    if (val.typeName && val.typeName.split('.').length > 1) {
+                        termData += '<span class="inputTag term" data-id="tagClick" data-href="' + val.typeName + '"><span class="inputValue">' + val.typeName + '</span><i class="fa fa-close" data-id="deleteTag" data-type="term"></i></span>';
                     }
                 });
                 this.ui.tagList.find("span.inputTag").remove();
@@ -247,15 +250,26 @@ define(['require',
                 this.ui.tagList.prepend(tagData);
                 this.ui.termList.prepend(termData);
             },
+            hideLoader: function() {
+                Utils.hideTitleLoader(this.$('.page-title .fontLoader'), this.$('.entityDetail'));
+            },
+            showLoader: function() {
+                Utils.showTitleLoader(this.$('.page-title .fontLoader'), this.$('.entityDetail'));
+            },
             onClickAddTagBtn: function(e) {
                 var that = this;
                 require(['views/tag/addTagModalView'], function(AddTagModalView) {
                     var view = new AddTagModalView({
                         vent: that.vent,
                         guid: that.id,
+                        tagList: _.map(that.collection.first().toJSON().classifications, function(obj) {
+                            return obj.typeName;
+                        }),
                         callback: function() {
                             that.fetchCollection();
-                        }
+                        },
+                        showLoader: that.showLoader.bind(that),
+                        hideLoader: that.hideLoader.bind(that)
                     });
                     view.modal.on('ok', function() {
                         Utils.showTitleLoader(that.$('.page-title .fontLoader'), that.$('.entityDetail'));
@@ -271,7 +285,9 @@ define(['require',
                         guid: that.id,
                         callback: function() {
                             that.fetchCollection();
-                        }
+                        },
+                        showLoader: that.showLoader.bind(that),
+                        hideLoader: that.hideLoader.bind(that)
                     });
                     view.modal.on('ok', function() {
                         Utils.showTitleLoader(that.$('.page-title .fontLoader'), that.$('.entityDetail'));