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/31 22:41:02 UTC

incubator-atlas git commit: ATLAS-1502: added configuration to restrict entity-types editable via UI

Repository: incubator-atlas
Updated Branches:
  refs/heads/master c8f9f363b -> a7870cded


ATLAS-1502: added configuration to restrict entity-types editable via UI

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/a7870cde
Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/a7870cde
Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/a7870cde

Branch: refs/heads/master
Commit: a7870cdede63eca6a11e1fd5d42824d0efd63186
Parents: c8f9f36
Author: kalyanikk <ka...@freestoneinfotech.com>
Authored: Tue Jan 31 14:49:13 2017 +0530
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Tue Jan 31 12:26:44 2017 -0800

----------------------------------------------------------------------
 dashboardv2/public/css/scss/tag.scss            |   4 +
 dashboardv2/public/js/main.js                   |  10 ++
 dashboardv2/public/js/router/Router.js          |  20 ++-
 .../detail_page/DetailPageLayoutView_tmpl.html  |   2 +-
 .../templates/search/SearchLayoutView_tmpl.html |   5 -
 .../search/SearchResultLayoutView_tmpl.html     |   8 +
 dashboardv2/public/js/utils/Overrides.js        |   9 +
 .../js/views/audit/AuditTableLayoutView.js      |   2 +-
 .../views/audit/CreateAuditTableLayoutView.js   |  24 ++-
 .../views/detail_page/DetailPageLayoutView.js   |  15 +-
 .../js/views/entity/CreateEntityLayoutView.js   | 173 +++++++++++--------
 .../js/views/search/SearchDetailLayoutView.js   |   5 +-
 .../public/js/views/search/SearchLayoutView.js  |  29 +---
 .../js/views/search/SearchResultLayoutView.js   |  88 +++++++---
 .../public/js/views/tag/addTagModalView.js      |   4 +-
 .../atlas/web/resources/AdminResource.java      |  30 ++++
 16 files changed, 276 insertions(+), 152 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/dashboardv2/public/css/scss/tag.scss
----------------------------------------------------------------------
diff --git a/dashboardv2/public/css/scss/tag.scss b/dashboardv2/public/css/scss/tag.scss
index 1f9561d..9cc6a3c 100644
--- a/dashboardv2/public/css/scss/tag.scss
+++ b/dashboardv2/public/css/scss/tag.scss
@@ -407,3 +407,7 @@ legend.scheduler-border {
 .topMargin {
     margin-top: 13px;
 }
+
+.entityLink {
+    font-size: 16px;
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/dashboardv2/public/js/main.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/main.js b/dashboardv2/public/js/main.js
index 2ddf1aa..2ba87a7 100644
--- a/dashboardv2/public/js/main.js
+++ b/dashboardv2/public/js/main.js
@@ -182,6 +182,16 @@ require(['App',
             if (response && response['atlas.entity.update.allowed'] !== undefined) {
                 Globals.entityUpdate = response['atlas.entity.update.allowed'];
             }
+            if (response && response['atlas.ui.editable.entity.types'] !== undefined) {
+                var entityTypeList = response['atlas.ui.editable.entity.types'].trim().split(",");
+                if (entityTypeList.length) {
+                    if (entityTypeList[0] === "*") {
+                        Globals.entityTypeConfList = [];
+                    } else if (entityTypeList.length > 0) {
+                        Globals.entityTypeConfList = entityTypeList;
+                    }
+                }
+            }
             App.start();
         }
     });

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/dashboardv2/public/js/router/Router.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/router/Router.js b/dashboardv2/public/js/router/Router.js
index fa4a08a..7394946 100644
--- a/dashboardv2/public/js/router/Router.js
+++ b/dashboardv2/public/js/router/Router.js
@@ -171,7 +171,6 @@ define([
                         'collection': that.tagCollection
                     }));
                 } else {
-
                     App.rSideNav.currentView.RTagLayoutView.currentView.manualRender(tagName);
                     App.rSideNav.currentView.selectTab();
                 }
@@ -191,7 +190,9 @@ define([
                 'views/site/Header',
                 'views/business_catalog/BusinessCatalogLayoutView',
                 'views/business_catalog/SideNavLayoutView',
-            ], function(Header, BusinessCatalogLayoutView, SideNavLayoutView) {
+                'views/search/SearchDetailLayoutView',
+            ], function(Header, BusinessCatalogLayoutView, SideNavLayoutView, SearchDetailLayoutView) {
+                var paramObj = Utils.getUrlState.getQueryParams();
                 App.rNHeader.show(new Header({ 'globalVent': that.globalVent }));
                 if (!App.rSideNav.currentView) {
                     App.rSideNav.show(new SideNavLayoutView({
@@ -206,8 +207,16 @@ define([
                         App.rSideNav.currentView.RBusinessCatalogLayoutView.currentView.manualRender(undefined, true);
                     }
                 }
-                App.rNContent.$el.html('');
-                App.rNContent.destroy();
+                if (Globals.entityCreate && Utils.getUrlState.isSearchTab()) {
+                    App.rNContent.show(new SearchDetailLayoutView({
+                        'globalVent': that.globalVent,
+                        'value': paramObj,
+                        'initialView': true
+                    }))
+                } else {
+                    App.rNContent.$el.html("");
+                    App.rNContent.destroy();
+                }
             });
         },
         searchResult: function() {
@@ -232,7 +241,8 @@ define([
                 App.rSideNav.currentView.selectTab();
                 App.rNContent.show(new SearchDetailLayoutView({
                     'globalVent': that.globalVent,
-                    'value': paramObj
+                    'value': paramObj,
+                    'initialView': paramObj.query.trim().length === 0
                 }));
             });
         },

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
index 1de3608..95cf62a 100644
--- a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
@@ -23,7 +23,7 @@
             <a href="javascript:void(0);" class="backButton" data-id="backButton"><i class="fa fa-chevron-left"></i>  Back To Results</a>
         </div>
         <h1><span  data-id="title"></span></h1> {{#if entityUpdate}}
-        <button data-id="editButton" class="btn btn-default pull-right editbutton" id="editText"><i class="fa fa-pencil"></i></button>
+        <button data-id="editButton" style="display:none" class="btn btn-default pull-right editbutton" id="editText"><i class="fa fa-pencil"></i></button>
         {{/if}}
         <div class="tagTerm">
             <span class="tagSpan">Tags:</span>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html b/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
index 7301ebc..5ccfe18 100644
--- a/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
@@ -15,11 +15,6 @@
  * limitations under the License.
 -->
 <div class="row row-margin-bottom">
-    {{#if entityCreate}}
-    <div class="col-sm-12">
-        <button class="btn btn-atlasAction btn-atlas pull-left" data-id="createEntity"><i class="fa fa-plus"></i> Create Entity</button>
-    </div>
-    {{/if}}
     <div class="col-sm-12" style="margin:15px 0px;">
         <div class="row">
             <div class="col-md-6">

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/dashboardv2/public/js/templates/search/SearchResultLayoutView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/search/SearchResultLayoutView_tmpl.html b/dashboardv2/public/js/templates/search/SearchResultLayoutView_tmpl.html
index 32a0083..eece7d2 100644
--- a/dashboardv2/public/js/templates/search/SearchResultLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/search/SearchResultLayoutView_tmpl.html
@@ -32,6 +32,14 @@
             </ul>
         </div>
         <div id="r_searchResultTableLayoutView">
+            {{#if entityCreate}}
+            <div class="entityLink" style="display:none">
+                <h1><b>Atlas Search</b></h1>
+                <p class="entityLink">Search Atlas for existing entities or
+                    <a href="javascript:void(0)" data-id='createEntity'> create new entity </a><i class="fa fa-question-circle" aria-hidden="true"></i>
+                </p>
+            </div>
+            {{/if}}
         </div>
     </div>
 </div>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/dashboardv2/public/js/utils/Overrides.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/Overrides.js b/dashboardv2/public/js/utils/Overrides.js
index d6d9b6c..b6fc17c 100644
--- a/dashboardv2/public/js/utils/Overrides.js
+++ b/dashboardv2/public/js/utils/Overrides.js
@@ -40,6 +40,15 @@ define(['require', 'utils/Utils', 'marionette', 'backgrid', 'asBreadcrumbs', 'jq
             })
         ]);
     }
+    _.mixin({
+        isEmptyArray: function(val) {
+            if (val && _.isArray(val)) {
+                return _.isEmpty(val);
+            } else {
+                return false;
+            }
+        }
+    });
 
     // For placeholder support 
     if (!('placeholder' in HTMLInputElement.prototype)) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/dashboardv2/public/js/views/audit/AuditTableLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/audit/AuditTableLayoutView.js b/dashboardv2/public/js/views/audit/AuditTableLayoutView.js
index dd4adda..2c0bc8c 100644
--- a/dashboardv2/public/js/views/audit/AuditTableLayoutView.js
+++ b/dashboardv2/public/js/views/audit/AuditTableLayoutView.js
@@ -147,7 +147,7 @@ define(['require',
                         that.$('.fontLoader').hide();
                         that.$('.auditTable').show();
                         that.renderOffset(options);
-                        if ((that.entityCollection.models.length < that.count && that.currPage == 1) && that.next == that.entityCollection.last().get('eventKey')) {
+                        if (that.entityCollection && (that.entityCollection.models.length < that.count && that.currPage == 1) && that.next == that.entityCollection.last().get('eventKey')) {
                             options.next.attr('disabled', true);
                             options.previous.removeAttr("disabled");
                         } else {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/dashboardv2/public/js/views/audit/CreateAuditTableLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/audit/CreateAuditTableLayoutView.js b/dashboardv2/public/js/views/audit/CreateAuditTableLayoutView.js
index 2b43b59..330809f 100644
--- a/dashboardv2/public/js/views/audit/CreateAuditTableLayoutView.js
+++ b/dashboardv2/public/js/views/audit/CreateAuditTableLayoutView.js
@@ -20,8 +20,9 @@ define(['require',
     'backbone',
     'hbs!tmpl/audit/CreateAuditTableLayoutView_tmpl',
     'utils/Enums',
-    'utils/CommonViewFunction'
-], function(require, Backbone, CreateAuditTableLayoutViewTmpl, Enums, CommonViewFunction) {
+    'utils/CommonViewFunction',
+    'utils/Utils'
+], function(require, Backbone, CreateAuditTableLayoutViewTmpl, Enums, CommonViewFunction, Utils) {
     'use strict';
 
     var CreateAuditTableLayoutView = Backbone.Marionette.LayoutView.extend(
@@ -65,11 +66,17 @@ define(['require',
                 if (this.entityModel.get('details').search('{') >= 0) {
                     var appendedString = "{" + this.entityModel.get('details') + "}";
                     var auditData = appendedString.split('"')[0].split(':')[0].split("{")[1];
-                    var detailsObject = JSON.parse(appendedString.replace("{" + auditData + ":", '{"' + auditData + '":'))[auditData];
+                    try {
+                        var detailsObject = JSON.parse(appendedString.replace("{" + auditData + ":", '{"' + auditData + '":'))[auditData];
+                    } catch (err) {
+                        Utils.serverErrorHandler();
+                    }
                     //Append string for JSON parse
-                    var valueObject = detailsObject.values;
-                    if (this.action == Enums.auditAction.TAG_ADD) {
-                        this.ui.auditHeaderValue.html('<th>' + Enums.auditAction.TAG_ADD + '</th>');
+                    if (detailsObject) {
+                        var valueObject = detailsObject.values;
+                    }
+                    if ((this.action == Enums.auditAction.TAG_ADD || Enums.auditAction.ENTITY_CREATE) && detailsObject) {
+                        this.ui.auditHeaderValue.html('<th>' + (this.action === Enums.auditAction.ENTITY_CREATE ? Enums.auditAction.ENTITY_CREATE : Enums.auditAction.TAG_ADD) + '</th>');
                         this.ui.auditValue.html("<tr><td>" + _.escape(detailsObject.typeName) + "</td></tr>");
                     } else {
                         this.ui.auditHeaderValue.html('<th>Key</th><th>New Value</th>');
@@ -84,9 +91,8 @@ define(['require',
                         }
                     }
                 } else if (this.action == Enums.auditAction.TAG_DELETE || Enums.auditAction.ENTITY_DELETE) {
-                    //var appendedString = this.entityModel.get('details').split(':');
-                    this.ui.auditHeaderValue.html('<th>' + this.action + '</th>');
-                    this.ui.auditValue.html("<tr><td>" + this.entityObject.name + "</td></tr>");
+                    this.ui.auditHeaderValue.html('<th>' + Enums.auditAction.TAG_DELETE || Enums.auditAction.ENTITY_DELETE + '</th>');
+                    this.ui.auditValue.html("<tr><td>" + (this.entityObject.name || this.entityObject.qualifiedName) + "</td></tr>");
                 }
 
             },

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/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 c959229..d778e3e 100644
--- a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
+++ b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
@@ -164,13 +164,21 @@ define(['require',
                         } else {
                             this.addTagToTerms([]);
                         }
+                        if (Globals.entityTypeConfList && _.isEmptyArray(Globals.entityTypeConfList)) {
+                            this.ui.editButton.show();
+                        } else {
+                            if (_.contains(Globals.entityTypeConfList, collectionJSON.typeName)) {
+                                this.ui.editButton.show();
+                            }
+                        }
                     }
                     this.hideLoader();
-                    this.auditVent.trigger("reset:collection");
                     this.renderEntityDetailTableLayoutView();
+                    this.renderAuditTableLayoutView(this.id, collectionJSON.attributes);
                     this.renderTagTableLayoutView(tagGuid);
                     this.renderTermTableLayoutView(tagGuid);
-                    this.renderAuditTableLayoutView(this.id, collectionJSON.attributes);
+                    this.renderLineageLayoutView(this.id);
+                    this.renderSchemaLayoutView(this.id);
                 }, this);
                 this.listenTo(this.collection, 'error', function(model, response) {
                     this.$('.fontLoader').hide();
@@ -185,9 +193,6 @@ define(['require',
                 var that = this;
                 Utils.showTitleLoader(this.$('.page-title .fontLoader'), this.$('.entityDetail'));
                 this.$('.fontLoader').show(); // to show tab loader
-                this.renderLineageLayoutView(this.id);
-                this.renderSchemaLayoutView(this.id);
-
             },
             fetchCollection: function() {
                 this.collection.fetch({ reset: true });

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js b/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js
index 9f4e1d7..1491b2e 100644
--- a/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js
+++ b/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js
@@ -21,7 +21,6 @@ define(['require',
     'hbs!tmpl/entity/CreateEntityLayoutView_tmpl',
     'utils/Utils',
     'collection/VTagList',
-    'collection/VCommonList',
     'collection/VEntityList',
     'models/VEntity',
     'modules/Modal',
@@ -30,8 +29,9 @@ define(['require',
     'moment',
     'utils/UrlLinks',
     'collection/VSearchList',
-    'utils/Enums'
-], function(require, Backbone, CreateEntityLayoutViewTmpl, Utils, VTagList, VCommonList, VEntityList, VEntity, Modal, Messages, datepicker, moment, UrlLinks, VSearchList, Enums) {
+    'utils/Enums',
+    'utils/Globals'
+], function(require, Backbone, CreateEntityLayoutViewTmpl, Utils, VTagList, VEntityList, VEntity, Modal, Messages, datepicker, moment, UrlLinks, VSearchList, Enums, Globals) {
 
     var CreateEntityLayoutView = Backbone.Marionette.LayoutView.extend(
         /** @lends CreateEntityLayoutView */
@@ -53,9 +53,7 @@ define(['require',
             ui: {
                 entityName: "[data-id='entityName']",
                 entityList: "[data-id='entityList']",
-                description: "[data-id='description']",
                 entityInputData: "[data-id='entityInputData']",
-                entityLegend: "[data-id='entityLegend']",
                 toggleRequired: 'input[name="toggleRequired"]',
                 assetName: "[data-id='assetName']",
                 entityInput: "[data-id='entityInput']"
@@ -77,7 +75,6 @@ define(['require',
                 _.extend(this, _.pick(options, 'guid', 'callback', 'showLoader'));
                 var that = this,
                     entityTitle, okLabel;
-                this.entityDetailCollection = new VCommonList();
                 this.searchCollection = new VSearchList();
                 this.searchCollection.url = UrlLinks.searchApiUrl(Enums.searchUrlType.DSL);
                 this.selectStoreCollection = new Backbone.Collection();
@@ -187,7 +184,15 @@ define(['require',
                         return model.get('name');
                     }
                     this.collection.fullCollection.sort().each(function(val) {
-                        str += '<option>' + _.escape(val.get("name")) + '</option>';
+                        if (Globals.entityTypeConfList) {
+                            if (_.isEmptyArray(Globals.entityTypeConfList)) {
+                                str += '<option>' + _.escape(val.get("name")) + '</option>';
+                            } else {
+                                if (_.contains(Globals.entityTypeConfList, val.get("name"))) {
+                                    str += '<option>' + _.escape(val.get("name")) + '</option>';
+                                }
+                            }
+                        }
                     });
                     this.ui.entityList.html(str);
                 }
@@ -207,6 +212,23 @@ define(['require',
                 }
 
             },
+            longValidation: function(that) {
+                that.$('input[data-type="long"]').on('keydown', function(e) {
+                    var regex = /^[0-9]*((?=[^.]|$))?$/; // allow only numbers [0-9] 
+                    if (!regex.test(e.currentTarget.value)) {
+                        return false;
+                    }
+                });
+                that.$('input[data-type="long"]').on('keyup click', function(e) {
+                    e.currentTarget.value = e.currentTarget.value;
+                    var regex = /^[0-9]*((?=[^.]|$))?$/; // allow only numbers [0-9] 
+                    if (!regex.test(e.currentTarget.value)) {
+                        var txtfld = e.currentTarget;
+                        var newtxt = txtfld.value.slice(0, txtfld.value.length - 1);
+                        txtfld.value = newtxt;
+                    }
+                }); // IE9 allow input type number
+            },
             onEntityChange: function(e, value) {
                 this.modal.$el.find('button.ok').prop("disabled", false);
                 var that = this,
@@ -235,37 +257,31 @@ define(['require',
                                 });
                             }
                         });
-                        that.$('input[data-type="long"]').each(function() {
-                            if (!$(this).data('datepicker')) {
-                                $(this).datetimepicker({
-                                    format: 'DD MMMM YYYY, HH:mm',
-                                    showTodayButton: true,
-                                    showClose: true
-                                });
-                            }
-                        });
+                        that.longValidation(that);
                         // IE9 allow input type number
                         that.$('input[data-type="int"]').on('keydown', function(e) {
-                            var regex = /^[0-9]*([.](?=[^.]|$))*(?:\.\d{1,2})?$/; // allow only numbers [0-9] 
+                            var regex = /^[0-9]*((?=[^.]|$))?$/; // allow only numbers [0-9] 
                             if (!regex.test(e.currentTarget.value)) {
                                 return false;
                             }
                         });
-                        if (that.ui.entityInputData.find('select.true,input.true').length === 0) {
+                        if (that.ui.entityInputData.find('fieldset').length > 0 && that.ui.entityInputData.find('select.true,input.true').length === 0) {
                             that.requiredAllToggle(that.ui.entityInputData.find('select.true,input.true').length === 0);
                             that.ui.toggleRequired.prop('checked', true);
-
                         }
                         // IE9 allow input type number
                         that.$('input[data-type="int"]').on('keyup click', function(e) {
                             e.currentTarget.value = e.currentTarget.value;
-                            var regex = /^[0-9]*([.](?=[^.]|$))*(?:\.\d{1,2})?$/; // allow only numbers [0-9] 
+                            var regex = /^[0-9]*((?=[^.]|$))?$/; // allow only numbers [0-9] 
                             if (!regex.test(e.currentTarget.value)) {
                                 var txtfld = e.currentTarget;
                                 var newtxt = txtfld.value.slice(0, txtfld.value.length - 1);
                                 txtfld.value = newtxt;
                             }
                         });
+                        that.$('select[data-type="array<string>"]').each(function() {
+                            that.addJsonSearchData(that.arryaType);
+                        });
                     },
                     silent: true
                 });
@@ -278,7 +294,6 @@ define(['require',
                     if (value.isOptional == true) {
                         alloptional = true;
                     }
-
                     attributeInput += that.getContainer(value);
                 });
                 if (attributeInput !== "") {
@@ -298,7 +313,7 @@ define(['require',
                     this.ui.entityInputData.find('div.true').hide();
                 }
                 if (!('placeholder' in HTMLInputElement.prototype)) {
-                    this.ui.entityInputData.find('input,select,textarea').placeholder();
+                    this.ui.entityInputData.find("input,select,textarea").placeholder();
                 }
             },
             getContainer: function(value) {
@@ -326,9 +341,6 @@ define(['require',
                         if (value.typeName === "date" && dataValue) {
                             entityValue = moment(dataValue).format("DD MMMM YYYY");
                         }
-                        if (value.typeName === "long") {
-                            entityValue = moment(dataValue).format("DD MMMM YYYY, HH:mm");
-                        }
                     }
                 }
                 if (value.typeName === "string" || value.typeName === "long" || value.typeName === "int" || value.typeName === "boolean" || value.typeName === "date") {
@@ -350,7 +362,7 @@ define(['require',
                         changeDatatype = value.typeName;
                     } else {
                         if (value.typeName === "array<string>") {
-                            changeDatatype = value.typeName;
+                            this.arryaType = value.typeName;
                         } else {
                             changeDatatype = value.typeName.split('<')[1].split('>')[0];
                         }
@@ -358,7 +370,7 @@ define(['require',
                     $.extend(that.searchCollection.queryParams, { query: changeDatatype });
                     that.searchCollection.fetch({ reset: true });
                     return '<select class="form-control row-margin-bottom entityInputBox ' + (value.isOptional === true ? "false" : "true") + '" data-type="' + value.typeName +
-                        '" data-key="' + value.name + '"data-id="entitySelectData" data-queryData="' + changeDatatype + '">' + (this.guid ? entityValue : "") + '</select>';
+                        '" data-key="' + value.name + '"data-id="entitySelectData" data-queryData="' + value.typeName + '">' + (this.guid ? entityValue : "") + '</select>';
                 }
             },
             getSelect: function(value) {
@@ -385,17 +397,13 @@ define(['require',
                                     });
                                 }
                             });
-                            that.$('input[data-type="long"]').each(function() {
-                                if (!$(this).data('datepicker')) {
-                                    $(this).datetimepicker({
-                                        format: 'DD MMMM YYYY, HH:mm',
-                                        showTodayButton: true,
-                                        showClose: true
-                                    });
-                                }
-                            });
+                            that.longValidation(that);
                             that.hideLoader();
                         }
+                        if (that.ui.entityInputData.find('select.true,input.true').length === 0) {
+                            that.requiredAllToggle(that.ui.entityInputData.find('select.true,input.true').length === 0);
+                            that.ui.toggleRequired.prop('checked', true);
+                        }
                         that.$('select[data-type="boolean"]').each(function(value, key) {
                             var dataKey = $(key).data('key');
                             if (that.entityData) {
@@ -403,12 +411,10 @@ define(['require',
                                 this.value = setValue;
                             }
                         });
-
                     },
                     silent: true
                 });
             },
-
             okButton: function() {
                 var that = this;
                 this.showLoader();
@@ -421,6 +427,7 @@ define(['require',
                     if ($(this).val() && $(this).val().trim) {
                         value = $(this).val().trim();
                     }
+
                     if ($(this).hasClass("true")) {
                         if (value == "" || value == undefined) {
                             if ($(this).data('select2')) {
@@ -437,8 +444,8 @@ define(['require',
                     var dataTypeEnitity = $(this).data('type');
                     var datakeyEntity = $(this).data('key');
                     var selectDataType = $(this).data('querydata');
-                    var pickKey = $(this).data('pickkey');
-                    if (typeof datakeyEntity === 'string' && datakeyEntity.indexOf("Time") > -1) {
+                    // var pickKey = $(this).data('pickkey');
+                    if (typeof dataTypeEnitity === 'string' && datakeyEntity.indexOf("Time") > -1) {
                         entityAttribute[datakeyEntity] = Date.parse($(this).val());
                     } else if (dataTypeEnitity == "string" || dataTypeEnitity === "long" || dataTypeEnitity === "int" || dataTypeEnitity === "boolean" || dataTypeEnitity == "date") {
                         entityAttribute[datakeyEntity] = $(this).val();
@@ -450,35 +457,40 @@ define(['require',
                                     if (arrayEmptyValueCheck === "") {
                                         return;
                                     }
-                                    if (dataTypeEnitity === "array<string>" || dataTypeEnitity === "map<string,string>") {
-                                        parseData = value;
+                                    if (dataTypeEnitity === "array<string>") {
+                                        var parseData = value;
                                     } else {
                                         if (that.selectStoreCollection.length) {
                                             var parseData = value.map(function(val) {
                                                 var temp = {} // I9 support;
-                                                temp[pickKey] = val;
+                                                temp['labelName'] = val;
                                                 var valueData = that.selectStoreCollection.findWhere(temp).toJSON();
-                                                valueData['guid'] = valueData.id;
+                                                valueData['guid'] = valueData.guid;
                                                 return valueData;
                                             })
                                         }
                                     }
                                 } else {
-                                    if (that.selectStoreCollection.length && pickKey) {
-
+                                    if (that.selectStoreCollection.length) {
                                         var temp = {} // I9 support;
-                                        temp[pickKey] = $(this).val();
+                                        temp['labelName'] = $(this).val();
                                         var parseData = that.selectStoreCollection.findWhere(temp).toJSON();
-                                        parseData['guid'] = parseData.id || parseData['$id$'].id;
+                                        parseData['guid'] = parseData.guid;
                                     }
                                     // Object but maptype
-                                    if (!pickKey) {
-                                        parseData = JSON.parse($(this).val());
+                                    if (!temp['labelName']) {
+                                        try {
+                                            parseData = JSON.parse($(this).val());
+                                        } catch (err) {
+                                            Utils.serverErrorHandler();
+                                        }
                                     }
                                 }
+                            }
+                            if (parseData) {
                                 entityAttribute[datakeyEntity] = parseData
-                                $(this).removeClass('errorClass');
                             }
+                            $(this).removeClass('errorClass');
                         } catch (e) {
                             $(this).addClass('errorClass');
                             that.validateError = e;
@@ -510,11 +522,17 @@ define(['require',
                         data: JSON.stringify(entityJson),
                         type: this.guid ? "PUT" : "POST",
                         success: function(model, response) {
-                            that.callback();
                             that.modal.close();
                             Utils.notifySuccess({
                                 content: "entity " + Messages[that.guid ? 'editSuccessMessage' : 'addSuccessMessage']
                             });
+                            if (that.guid && that.callback) {
+                                that.callback();
+                            } else {
+                                if (model.entitiesMutated && (model.entitiesMutated.CREATE || model.entitiesMutated.UPDATE)) {
+                                    that.setUrl('#!/detailPage/' + (model.entitiesMutated.CREATE ? model.entitiesMutated.CREATE[0].guid : model.entitiesMutated.UPDATE[0].guid), true);
+                                }
+                            }
                         },
                         complete: function() {
                             that.hideLoader();
@@ -522,6 +540,16 @@ define(['require',
                     });
                 }
             },
+            setUrl: function(url, create) {
+                Utils.setUrl({
+                    url: url,
+                    mergeBrowserUrl: false,
+                    trigger: true,
+                    updateTabState: function() {
+                        return { tagUrl: this.url, stateChanged: true };
+                    }
+                });
+            },
             showLoader: function() {
                 this.$('.entityLoader').show();
                 this.$('.entityInputData').hide();
@@ -530,35 +558,35 @@ define(['require',
                 this.$('.entityLoader').hide();
                 this.$('.entityInputData').show();
             },
-            addJsonSearchData: function(isError) {
+            addJsonSearchData: function(arrStingType) {
                 var that = this,
                     typename,
                     str = '';
-                if (isError) {
-                    typename = isError.responseJSON.error.split(": ")[1];
+                if (arrStingType) {
+                    typename = arrStingType;
                 } else {
                     if (this.searchCollection.length) {
-                        typename = this.searchCollection.first().get("$typeName$");
+                        typename = this.searchCollection.first().get("typeName");
                         this.selectStoreCollection.push(this.searchCollection.fullCollection.models);
                         var labelName = "";
                         _.each(this.searchCollection.fullCollection.models, function(value, key) {
-                            if (value.get("qualifiedName")) {
-                                labelName = "qualifiedName";
-                            } else if (value.get("name")) {
-                                labelName = "name";
-                            } else if (value.get("id")) {
-                                labelName = "id";
+                            var obj = value.toJSON();
+
+                            labelName = (_.escape(obj.attributes && obj.attributes.name ? obj.attributes.name : null) || _.escape(obj.displayText) || obj.guid);
+                            value.set('labelName', labelName);
+                            if (labelName) {
+                                str += '<option>' + _.escape(labelName) + '</option>';
                             }
-                            str += '<option>' + _.escape(value.get(labelName)) + '</option>';
                         });
+                    } else {
+
                     }
                 }
                 this.$('select[data-queryData="' + typename + '"]').html(str);
-                this.$('select[data-queryData="' + typename + '"]').attr('data-pickkey', labelName);
-                this.$('select[data-queryData="' + typename + '"]').each(function(value, key) {
+                $('select[data-id="' + 'entitySelectData' + '"]').each(function(value, key) {
                     var keyData = $(this).data("key");
                     var typeData = $(this).data("type");
-                    var placeholderName = "Select a " + typename + " from the dropdown list";
+                    var placeholderName = "Select a " + typeData + " from the dropdown list";
                     var $this = $(this);
                     $this.attr("multiple", ($this.data('type').indexOf("array") === -1 ? false : true))
                     if (that.guid) {
@@ -567,15 +595,16 @@ define(['require',
                         }
                         var dataValue = that.entityData.get("attributes")[keyData];
                         that.selectStoreCollection.each(function(value) {
+                            var obj = value.toJSON();
                             if (dataValue !== null && _.isArray(dataValue)) {
                                 _.each(dataValue, function(obj) {
-                                    if (obj.guid === value.get("id")) {
-                                        selectedValue.push(value.get("qualifiedName") || value.get("name") || value.get("id"));
+                                    if (obj.guid === value.attributes.guid) {
+                                        selectedValue.push(value.attributes.labelName);
                                     }
                                 });
                             } else if (dataValue !== null) {
-                                if (dataValue.guid === value.get("id")) {
-                                    selectedValue.push(value.get("qualifiedName") || value.get("name") || value.get("id"));
+                                if (dataValue.guid === value.attributes.guid) {
+                                    selectedValue.push(value.attributes.labelName);
                                 }
                             }
                         });
@@ -586,7 +615,9 @@ define(['require',
                                 var dataValue = that.entityData.get("attributes")[keyData];
                                 if (dataValue !== null) {
                                     _.each(dataValue, function(obj) {
-                                        str += '<option>' + _.escape(obj) + '</option>';
+                                        if (!_.isObject(obj)) {
+                                            str += '<option>' + _.escape(obj) + '</option>';
+                                        }
                                     });
                                     $this.html(str);
                                 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/dashboardv2/public/js/views/search/SearchDetailLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/search/SearchDetailLayoutView.js b/dashboardv2/public/js/views/search/SearchDetailLayoutView.js
index 0ed1c38..16e3fa1 100644
--- a/dashboardv2/public/js/views/search/SearchDetailLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchDetailLayoutView.js
@@ -43,7 +43,7 @@ define(['require',
              * @constructs
              */
             initialize: function(options) {
-                _.extend(this, _.pick(options, 'globalVent', 'value'));
+                _.extend(this, _.pick(options, 'globalVent', 'value', 'initialView'));
             },
             bindEvents: function() {},
             onRender: function() {
@@ -63,7 +63,8 @@ define(['require',
                     if (that.RSearchResultLayoutView) {
                         that.RSearchResultLayoutView.show(new SearchResultLayoutView({
                             value: value,
-                            tag: that.tag
+                            tag: that.tag,
+                            initialView: that.initialView
                         }));
                     }
                 });

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/dashboardv2/public/js/views/search/SearchLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/search/SearchLayoutView.js b/dashboardv2/public/js/views/search/SearchLayoutView.js
index bdb71a6..958b23b 100644
--- a/dashboardv2/public/js/views/search/SearchLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchLayoutView.js
@@ -43,14 +43,7 @@ define(['require',
                 searchBtn: '[data-id="searchBtn"]',
                 clearSearch: '[data-id="clearSearch"]',
                 typeLov: '[data-id="typeLOV"]',
-                refreshBtn: '[data-id="refreshBtn"]',
-                createEntity: "[data-id='createEntity']",
-            },
-
-            templateHelpers: function() {
-                return {
-                    entityCreate: Globals.entityCreate
-                };
+                refreshBtn: '[data-id="refreshBtn"]'
             },
 
             /** ui events hash */
@@ -72,7 +65,6 @@ define(['require',
                 events["click " + this.ui.clearSearch] = 'clearSearchData';
                 events["change " + this.ui.typeLov] = 'onChangeTypeList';
                 events["click " + this.ui.refreshBtn] = 'onRefreshButton';
-                events["click " + this.ui.createEntity] = 'onClickCreateEntity';
                 return events;
             },
             /**
@@ -132,7 +124,9 @@ define(['require',
                     return model.get('name').toLowerCase();
                 }
                 this.typecollection.fullCollection.sort().each(function(model) {
-                    str += '<option>' + _.escape(model.get("name")) + '</option>';
+                    if (model.get('category') == 'ENTITY') {
+                        str += '<option>' + _.escape(model.get("name")) + '</option>';
+                    }
                 });
                 that.ui.typeLov.html(str);
             },
@@ -257,20 +251,7 @@ define(['require',
                     mergeBrowserUrl: false,
                     trigger: true
                 });
-            },
-            onClickCreateEntity: function(e) {
-                var that = this;
-                $(e.currentTarget).blur();
-                require([
-                    'views/entity/CreateEntityLayoutView'
-                ], function(CreateEntityLayoutView) {
-                    var view = new CreateEntityLayoutView({
-                        callback: function() {
-                            that.fetchCollection();
-                        }
-                    });
-                });
-            },
+            }
         });
     return SearchLayoutView;
 });

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/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 cbfe08e..5c2754b 100644
--- a/dashboardv2/public/js/views/search/SearchResultLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchResultLayoutView.js
@@ -58,9 +58,14 @@ define(['require',
                 nextData: "[data-id='nextData']",
                 pageRecordText: "[data-id='pageRecordText']",
                 addAssignTag: "[data-id='addAssignTag']",
-                editEntityButton: "[data-id='editEntityButton']"
+                editEntityButton: "[data-id='editEntityButton']",
+                createEntity: "[data-id='createEntity']",
+            },
+            templateHelpers: function() {
+                return {
+                    entityCreate: Globals.entityCreate
+                };
             },
-
             /** ui events hash */
             events: function() {
                 var events = {};
@@ -109,6 +114,7 @@ define(['require',
                 events["click " + this.ui.nextData] = "onClicknextData";
                 events["click " + this.ui.previousData] = "onClickpreviousData";
                 events["click " + this.ui.editEntityButton] = "onClickEditEntity";
+                events["click " + this.ui.createEntity] = 'onClickCreateEntity';
                 return events;
             },
             /**
@@ -116,7 +122,7 @@ define(['require',
              * @constructs
              */
             initialize: function(options) {
-                _.extend(this, _.pick(options, 'globalVent', 'vent', 'value'));
+                _.extend(this, _.pick(options, 'globalVent', 'vent', 'value', 'initialView'));
                 var pagination = "";
                 this.entityModel = new VEntity();
                 this.searchCollection = new VSearchList();
@@ -178,26 +184,32 @@ define(['require',
                 }, this);
             },
             onRender: function() {
-                var value = {},
-                    that = this;
-                if (this.value) {
-                    value = this.value;
-                } else {
-                    value = {
-                        'query': '',
-                        'searchType': 'fulltext'
-                    };
-                }
-                this.fetchCollection(value);
-                $('body').click(function(e) {
-                    var iconEvnt = e.target.nodeName;
-                    if (that.$('.popoverContainer').length) {
-                        if ($(e.target).hasClass('tagDetailPopover') || iconEvnt == "I") {
-                            return;
+                if (!this.initialView) {
+                    var value = {},
+                        that = this;
+                    if (this.value) {
+                        value = this.value;
+                    } else {
+                        value = {
+                            'query': '',
+                            'searchType': 'fulltext'
+                        };
+                    }
+                    this.fetchCollection(value);
+                    $('body').click(function(e) {
+                        var iconEvnt = e.target.nodeName;
+                        if (that.$('.popoverContainer').length) {
+                            if ($(e.target).hasClass('tagDetailPopover') || iconEvnt == "I") {
+                                return;
+                            }
+                            that.$('.popover.popoverTag').hide();
                         }
-                        that.$('.popover.popoverTag').hide();
+                    });
+                } else {
+                    if (Globals.entityTypeConfList) {
+                        this.$(".entityLink").show();
                     }
-                });
+                }
             },
             fetchCollection: function(value) {
                 var that = this;
@@ -264,13 +276,16 @@ define(['require',
                         }
                         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>';
+                        var resultText = that.searchCollection.queryParams.query;
+                        var multiAssignDataTerm = "",
+                            createEntityTag = "";
                         if (Globals.taxonomy) {
-                            var multiAssignDataTerm = '<a href="javascript:void(0)" class="inputAssignTag multiSelect" style="display:none" data-id="addTerm"><i class="fa fa-folder-o"></i>' + " " + 'Assign Term</a>';
-                            that.$('.searchResult').html(resultData + multiAssignDataTerm + multiAssignDataTag);
-                        } else {
-                            that.$('.searchResult').html(resultData + multiAssignDataTag);
+                            multiAssignDataTerm = '<a href="javascript:void(0)" class="inputAssignTag multiSelect" style="display:none" data-id="addTerm"><i class="fa fa-folder-o"></i>' + " " + 'Assign Term</a>';
                         }
-
+                        if (Globals.entityCreate && (resultText.indexOf("\`") != 0) && Globals.entityTypeConfList) {
+                            createEntityTag = "<p>If you do not find the entity in search result below then you can" + '<a href="javascript:void(0)" data-id="createEntity"> create new entity</a></p>';
+                        }
+                        that.$('.searchResult').html(resultData + multiAssignDataTag + multiAssignDataTerm + createEntityTag);
                     },
                     silent: true,
                     reset: true
@@ -341,7 +356,13 @@ define(['require',
                                 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>'
+                                    if (Globals.entityTypeConfList && _.isEmptyArray(Globals.entityTypeConfList)) {
+                                        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>'
+                                    } else {
+                                        if (_.contains(Globals.entityTypeConfList, obj.typeName)) {
+                                            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;
                             }
@@ -606,6 +627,19 @@ define(['require',
                         }
                     });
                 });
+            },
+            onClickCreateEntity: function(e) {
+                var that = this;
+                $(e.currentTarget).blur();
+                require([
+                    'views/entity/CreateEntityLayoutView'
+                ], function(CreateEntityLayoutView) {
+                    var view = new CreateEntityLayoutView({
+                        callback: function() {
+                            that.fetchCollection();
+                        }
+                    });
+                });
             }
         });
     return SearchResultLayoutView;

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/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 7317a95..3d00caf 100644
--- a/dashboardv2/public/js/views/tag/addTagModalView.js
+++ b/dashboardv2/public/js/views/tag/addTagModalView.js
@@ -98,8 +98,8 @@ define(['require',
                         });
                     }
                     if (obj.skipEntity.length) {
-                        var text = "<b>" + obj.skipEntity.join(', ') +
-                            "</b> <br/> entities selected have already been associated with <b>" + tagName +
+                        var text = "<b>" + obj.skipEntity.length + " of " + that.multiple.length +
+                            "</b> 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) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/a7870cde/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
index 54c46a8..3bdcc87 100755
--- a/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
+++ b/webapp/src/main/java/org/apache/atlas/web/resources/AdminResource.java
@@ -48,6 +48,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -65,6 +66,8 @@ public class AdminResource {
     private static final String isTaxonomyEnabled = "atlas.feature.taxonomy.enable";
     private static final String isEntityUpdateAllowed = "atlas.entity.update.allowed";
     private static final String isEntityCreateAllowed = "atlas.entity.create.allowed";
+    private static final String editableEntityTypes = "atlas.ui.editable.entity.types";
+    private static final String DEFAULT_EDITABLE_ENTITY_TYPES = "hdfs_path,hdfs_path,hbase_table,hbase_column,hbase_column_family,kafka_topic";
     private Response version;
     private ServiceState serviceState;
     private MetricsService metricsService;
@@ -213,6 +216,7 @@ public class AdminResource {
             responseData.put(isTaxonomyEnabled, enableTaxonomy);
             responseData.put(isEntityUpdateAllowed, isEntityUpdateAccessAllowed);
             responseData.put(isEntityCreateAllowed, isEntityCreateAccessAllowed);
+            responseData.put(editableEntityTypes, getEditableEntityTypes(configProperties));
             responseData.put("userName", userName);
             responseData.put("groups", groups);
 
@@ -244,4 +248,30 @@ public class AdminResource {
 
         return metrics;
     }
+
+    private String getEditableEntityTypes(PropertiesConfiguration config) {
+        String ret = DEFAULT_EDITABLE_ENTITY_TYPES;
+
+        if (config.containsKey(editableEntityTypes)) {
+            Object value = config.getProperty(editableEntityTypes);
+
+            if (value instanceof String) {
+                ret = (String)value;
+            } else if (value instanceof Collection) {
+                StringBuilder sb = new StringBuilder();
+
+                for (Object elem : ((Collection)value)) {
+                    if (sb.length() > 0) {
+                        sb.append(",");
+                    }
+
+                    sb.append(elem.toString());
+                }
+
+                ret = sb.toString();
+            }
+        }
+
+        return ret;
+    }
 }