atlas-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mad...@apache.org
Subject [1/4] incubator-atlas git commit: ATLAS-1193: UI to create/update entities
Date Fri, 16 Dec 2016 14:50:36 GMT
Repository: incubator-atlas
Updated Branches:
  refs/heads/master 1620284e4 -> b305ba505


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/edc4786b/dashboardv2/public/js/external_lib/datetimepicker/bootstrap-datetimepicker.min.css
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/external_lib/datetimepicker/bootstrap-datetimepicker.min.css b/dashboardv2/public/js/external_lib/datetimepicker/bootstrap-datetimepicker.min.css
new file mode 100644
index 0000000..e9ec816
--- /dev/null
+++ b/dashboardv2/public/js/external_lib/datetimepicker/bootstrap-datetimepicker.min.css
@@ -0,0 +1,5 @@
+/*!
+ * Datetimepicker for Bootstrap 3
+ * version : 4.14.30
+ * https://github.com/Eonasdan/bootstrap-datetimepicker/
+ */.bootstrap-datetimepicker-widget{list-style:none}.bootstrap-datetimepicker-widget.dropdown-menu{margin:2px 0;padding:4px;width:19em}@media (min-width:768px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}@media (min-width:992px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}@media (min-width:1200px){.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs{width:38em}}.bootstrap-datetimepicker-widget.dropdown-menu:after,.bootstrap-datetimepicker-widget.dropdown-menu:before{content:'';display:inline-block;position:absolute}.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before{border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,.2);top:-7px;left:7px}.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after{border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;top:-6px;left:8px}.bootstrap-datetime
 picker-widget.dropdown-menu.top:before{border-left:7px solid transparent;border-right:7px solid transparent;border-top:7px solid #ccc;border-top-color:rgba(0,0,0,.2);bottom:-7px;left:6px}.bootstrap-datetimepicker-widget.dropdown-menu.top:after{border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #fff;bottom:-6px;left:7px}.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before{left:auto;right:6px}.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after{left:auto;right:7px}.bootstrap-datetimepicker-widget .list-unstyled{margin:0}.bootstrap-datetimepicker-widget a[data-action]{padding:6px 0}.bootstrap-datetimepicker-widget a[data-action]:active{box-shadow:none}.bootstrap-datetimepicker-widget .timepicker-hour,.bootstrap-datetimepicker-widget .timepicker-minute,.bootstrap-datetimepicker-widget .timepicker-second{width:54px;font-weight:700;font-size:1.2em;margin:0}.bootstrap-datetimepicker-widget button[data-action]{padding:6px}.bootst
 rap-datetimepicker-widget .btn[data-action=incrementHours]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Increment Hours"}.bootstrap-datetimepicker-widget .btn[data-action=incrementMinutes]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Increment Minutes"}.bootstrap-datetimepicker-widget .btn[data-action=decrementHours]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Decrement Hours"}.bootstrap-datetimepicker-widget .btn[data-action=decrementMinutes]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Decrement Minutes"}.bootstrap-datetimepicker-widget .btn[data-action=showHours]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content
 :"Show Hours"}.bootstrap-datetimepicker-widget .btn[data-action=showMinutes]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Show Minutes"}.bootstrap-datetimepicker-widget .btn[data-action=togglePeriod]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Toggle AM/PM"}.bootstrap-datetimepicker-widget .btn[data-action=clear]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Clear the picker"}.bootstrap-datetimepicker-widget .btn[data-action=today]::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Set the date to today"}.bootstrap-datetimepicker-widget .picker-switch{text-align:center}.bootstrap-datetimepicker-widget .picker-switch::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflo
 w:hidden;clip:rect(0,0,0,0);border:0;content:"Toggle Date and Time Screens"}.bootstrap-datetimepicker-widget .picker-switch td{padding:0;margin:0;height:auto;width:auto;line-height:inherit}.bootstrap-datetimepicker-widget .picker-switch td span{line-height:2.5;height:2.5em;width:100%}.bootstrap-datetimepicker-widget table{width:100%;margin:0}.bootstrap-datetimepicker-widget table td,.bootstrap-datetimepicker-widget table th{text-align:center;border-radius:4px}.bootstrap-datetimepicker-widget table th{height:20px;line-height:20px;width:20px}.bootstrap-datetimepicker-widget table th.picker-switch{width:145px}.bootstrap-datetimepicker-widget table th.disabled,.bootstrap-datetimepicker-widget table th.disabled:hover{background:0 0;color:#777;cursor:not-allowed}.bootstrap-datetimepicker-widget table th.prev::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Previous Month"}.bootstrap-datetimepicker-widget table th.next
 ::after{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0;content:"Next Month"}.bootstrap-datetimepicker-widget table thead tr:first-child th{cursor:pointer}.bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#eee}.bootstrap-datetimepicker-widget table td{height:54px;line-height:54px;width:54px}.bootstrap-datetimepicker-widget table td.cw{font-size:.8em;height:20px;line-height:20px;color:#777}.bootstrap-datetimepicker-widget table td.day{height:20px;line-height:20px;width:20px}.bootstrap-datetimepicker-widget table td.day:hover,.bootstrap-datetimepicker-widget table td.hour:hover,.bootstrap-datetimepicker-widget table td.minute:hover,.bootstrap-datetimepicker-widget table td.second:hover{background:#eee;cursor:pointer}.bootstrap-datetimepicker-widget table td.new,.bootstrap-datetimepicker-widget table td.old{color:#777}.bootstrap-datetimepicker-widget table td.today{position:relative}.bootstrap-dateti
 mepicker-widget table td.today:before{content:'';display:inline-block;border:0 solid transparent;border-bottom-color:#337ab7;border-top-color:rgba(0,0,0,.2);position:absolute;bottom:4px;right:4px}.bootstrap-datetimepicker-widget table td.active,.bootstrap-datetimepicker-widget table td.active:hover{background-color:#337ab7;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.bootstrap-datetimepicker-widget table td.active.today:before{border-bottom-color:#fff}.bootstrap-datetimepicker-widget table td.disabled,.bootstrap-datetimepicker-widget table td.disabled:hover{background:0 0;color:#777;cursor:not-allowed}.bootstrap-datetimepicker-widget table td span{display:inline-block;width:54px;height:54px;line-height:54px;margin:2px 1.5px;cursor:pointer;border-radius:4px}.bootstrap-datetimepicker-widget table td span:hover{background:#eee}.bootstrap-datetimepicker-widget table td span.active{background-color:#337ab7;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,.25)}.bootstrap-datetimepicker-widg
 et table td span.old{color:#777}.bootstrap-datetimepicker-widget table td span.disabled,.bootstrap-datetimepicker-widget table td span.disabled:hover{background:0 0;color:#777;cursor:not-allowed}.bootstrap-datetimepicker-widget.usetwentyfour td.hour{height:27px;line-height:27px}.bootstrap-datetimepicker-widget.wider{width:21em}.bootstrap-datetimepicker-widget .datepicker-decades .decade{line-height:1.8em!important}.input-group.date .input-group-addon{cursor:pointer}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/edc4786b/dashboardv2/public/js/main.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/main.js b/dashboardv2/public/js/main.js
index 772d3d4..fe08754 100644
--- a/dashboardv2/public/js/main.js
+++ b/dashboardv2/public/js/main.js
@@ -94,6 +94,10 @@ require.config({
             'deps': ['d3'],
             'exports': ['d3-tip']
         },
+        'datetimepicker': {
+            'deps': ['jquery'],
+            'exports': 'datetimepicker'
+        },
         'dagreD3': {
             'deps': ['d3'],
             'exports': ['dagreD3']
@@ -130,10 +134,11 @@ require.config({
         'hbs': 'external_lib/require-handlebars-plugin/js/hbs',
         'i18nprecompile': 'external_lib/require-handlebars-plugin/js/i18nprecompile',
         'dagreD3': 'libs/dagre-d3/dagre-d3.min',
-        'select2': 'libs/select2/select2.min',
+        'select2': 'libs/select2/select2.full.min',
         'backgrid-select-all': 'libs/backgrid-select-all/backgrid-select-all.min',
         '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',
         'jquery-placeholder': 'libs/jquery-placeholder/js/jquery.placeholder',
         'platform': 'libs/platform/platform'
@@ -156,7 +161,7 @@ require(['App',
     'utils/Overrides',
     'bootstrap',
     'd3',
-    'select2' 
+    'select2'
 ], function(App, Router, CommonViewFunction, Globals, UrlLinks) {
     App.appRouter = new Router();
     CommonViewFunction.userDataFetch({

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/edc4786b/dashboardv2/public/js/models/VEntity.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/models/VEntity.js b/dashboardv2/public/js/models/VEntity.js
index 4347b62..2173534 100644
--- a/dashboardv2/public/js/models/VEntity.js
+++ b/dashboardv2/public/js/models/VEntity.js
@@ -70,8 +70,20 @@ define(['require',
             }, options);
 
             return this.constructor.nonCrudOperation.call(this, url, 'GET', options);
+        },
+        createOreditEntity: function(guid, options) {
+            var url;
+            if (guid) {
+                url = UrlLinks.entitiesApiUrl(guid);
+            } else {
+                url = UrlLinks.entitiesApiUrl();
+            }
+            options = _.extend({
+                contentType: 'application/json',
+                dataType: 'json'
+            }, options);
+            return this.constructor.nonCrudOperation.call(this, url, "", options);
         }
-
     }, {});
     return VEntity;
 });

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/edc4786b/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 f34bcea..e89555a 100644
--- a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
@@ -19,6 +19,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>
+    <button data-id="editButton" class="btn btn-default pull-right editbutton" id="editText"><i class="fa fa-pencil"></i></button>
     <div data-id="editBox" style="margin-bottom:10px;">
         <textarea class="well well-sm col-sm-12" data-id="descriptionTextArea"></textarea>
         <div class="clearfix" align="right">

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/edc4786b/dashboardv2/public/js/templates/entity/CreateEntityLayoutView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/entity/CreateEntityLayoutView_tmpl.html b/dashboardv2/public/js/templates/entity/CreateEntityLayoutView_tmpl.html
new file mode 100644
index 0000000..01f2aa0
--- /dev/null
+++ b/dashboardv2/public/js/templates/entity/CreateEntityLayoutView_tmpl.html
@@ -0,0 +1,46 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<form name="entityDefinitionform" class="css-form">
+    <!-- <h4 style="margin-bottom:30px"></h4> -->
+    <div class="form-group">
+        <div class="col-sm-12">
+            <div class="row">
+                {{#if guid}}
+                <div class="col-md-8">
+                    <label class="col-md-6 row-margin-bottom" data-id="assetName"></label>
+                </div>
+                {{else}}
+                <div class="col-md-8">
+                    <select class="form-control col-md-6 row-margin-bottom" data-id="entityList"></select>
+                </div>
+                {{/if}}
+                <div class="col-md-4">
+                    <span class="pull-left">Required</span>
+                    <label class="switch pull-left">
+                        <input type="checkbox" class="switch-input" name="toggleRequired" value="text">
+                        <div class="switch-slider"></div>
+                    </label>
+                    <span class="pull-left">All</span>
+                </div>
+            </div>
+        </div>
+        <div class="entityLoader" style="display:none">
+            <i class="fa fa-refresh fa-spin-custom"></i>
+        </div>
+        <div class="control-group entityInputData" data-id="entityInputData"></div>
+    </div>
+</form>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/edc4786b/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 db31046..8d7f874 100644
--- a/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
@@ -15,6 +15,9 @@
  * limitations under the License.
 -->
 <div class="row row-margin-bottom">
+    <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>
     <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/edc4786b/dashboardv2/public/js/utils/UrlLinks.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/UrlLinks.js b/dashboardv2/public/js/utils/UrlLinks.js
index a5288be..4071b07 100644
--- a/dashboardv2/public/js/utils/UrlLinks.js
+++ b/dashboardv2/public/js/utils/UrlLinks.js
@@ -29,11 +29,11 @@ define(['require', 'utils/Enums'], function(require, Enums) {
             return this.baseUrl + '/v1/taxonomies' + '/' + name + '/terms';
         },
         entitiesApiUrl: function(guid, name) {
-            var entitiesUrl = this.baseUrlV2 + '/entity/guid';
+            var entitiesUrl = this.baseUrlV2 + '/entity';
             if (guid && name) {
-                return entitiesUrl + '/' + guid + '/classification/' + name;
+                return entitiesUrl + '/guid/' + guid + '/classification/' + name;
             } else if (guid && !name) {
-                return entitiesUrl + '/' + guid;
+                return entitiesUrl + '/guid/' + guid;
             } else {
                 return entitiesUrl;
             }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/edc4786b/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 b2d2c7b..041204f 100644
--- a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
+++ b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
@@ -75,6 +75,7 @@ define(['require',
             /** ui events hash */
             events: function() {
                 var events = {};
+                events["click " + this.ui.editButton] = 'onClickEditEntity';
                 events["click " + this.ui.tagClick] = function(e) {
                     if (e.target.nodeName.toLocaleLowerCase() != "i") {
                         var scope = $(e.currentTarget);
@@ -358,6 +359,21 @@ define(['require',
                         term: true
                     }));
                 });
+            },
+            onClickEditEntity: function(e) {
+                var that = this;
+                $(e.currentTarget).blur();
+                require([
+                    'views/entity/CreateEntityLayoutView'
+                ], function(CreateEntityLayoutView) {
+                    var view = new CreateEntityLayoutView({
+                        guid: that.id,
+                        callback: function() {
+                            that.fetchCollection();
+                        }
+                    });
+
+                });
             }
         });
     return DetailPageLayoutView;

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/edc4786b/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
new file mode 100644
index 0000000..a3e0389
--- /dev/null
+++ b/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js
@@ -0,0 +1,613 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+define(['require',
+    'backbone',
+    'hbs!tmpl/entity/CreateEntityLayoutView_tmpl',
+    'utils/Utils',
+    'collection/VTagList',
+    'collection/VCommonList',
+    'collection/VEntityList',
+    'models/VEntity',
+    'modules/Modal',
+    'utils/Messages',
+    'datetimepicker',
+    'moment',
+    'utils/UrlLinks',
+    'collection/VSearchList',
+    'utils/Enums'
+], function(require, Backbone, CreateEntityLayoutViewTmpl, Utils, VTagList, VCommonList, VEntityList, VEntity, Modal, Messages, datepicker, moment, UrlLinks, VSearchList, Enums) {
+
+    var CreateEntityLayoutView = Backbone.Marionette.LayoutView.extend(
+        /** @lends CreateEntityLayoutView */
+        {
+            _viewName: 'CreateEntityLayoutView',
+
+            template: CreateEntityLayoutViewTmpl,
+
+            templateHelpers: function() {
+                return {
+                    guid: this.guid
+                };
+            },
+
+            /** Layout sub regions */
+            regions: {},
+
+            /** ui selector cache */
+            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']"
+            },
+            /** ui events hash */
+            events: function() {
+                var events = {};
+                events["change " + this.ui.entityList] = "onEntityChange";
+                events["change " + this.ui.toggleRequired] = function(e) {
+                    this.requiredAllToggle(e.currentTarget.checked)
+                };
+                return events;
+            },
+            /**
+             * intialize a new CreateEntityLayoutView Layout
+             * @constructs
+             */
+            initialize: function(options) {
+                _.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();
+                this.entityModel = new VEntity();
+                if (this.guid) {
+                    this.collection = new VEntityList();
+                    this.collection.modelAttrName = "createEntity"
+                } else {
+                    this.collection = new VTagList();
+                }
+                this.asyncFetchCounter = 0;
+                this.required = true;
+                if (this.guid) {
+                    entityTitle = 'Edit entity';
+                    okLabel = 'Update';
+                } else {
+                    entityTitle = 'Create entity';
+                    okLabel = 'Create';
+                }
+                this.modal = new Modal({
+                    title: entityTitle,
+                    content: this,
+                    cancelText: "Cancel",
+                    okText: okLabel,
+                    allowCancel: true,
+                    okCloses: false,
+                    resizable: true,
+                    resizableOpts: {
+                        minWidth: 600,
+                        minHeight: 284,
+                        handles: "n, e, s, w",
+                        resize: function(event, ui) {
+                            that.modal.$el.find('.modal-body').css('min-height', ui.size.height - 134 + 'px');
+                            that.modal.$el.find('.modal-body').css('max-height', ui.size.height - 134 + 'px');
+                        }
+                    }
+                }).open();
+                var enable = false;
+                this.ui.entityList.val("");
+                $(this.ui.entityInputData).on('keyup change dp.change', that.modal.$el.find('input select textarea'), function(e) {
+                    that.ui.entityInputData.find("input,select,textarea").each(function() {
+                        if (this.value !== "") {
+                            if ($(this).data('select2')) {
+                                $(this).data('select2').$container.removeClass("errorClass")
+                            } else {
+                                $(this).removeClass('errorClass');
+                            }
+                        }
+                    });
+                });
+                this.modal.on('ok', function(e) {
+                    that.okButton();
+                });
+                this.modal.on('closeModal', function() {
+                    that.modal.trigger('cancel');
+                });
+            },
+            bindEvents: function() {
+                var that = this;
+                this.listenTo(this.collection, "reset", function() {
+                    --this.asyncFetchCounter;
+                    this.entityCollectionList();
+                }, this);
+                this.listenTo(this.collection, 'error', function() {
+                    --this.asyncFetchCounter
+                    this.hideLoader();
+                }, this);
+                this.listenTo(this.searchCollection, "reset", function() {
+                    this.addJsonSearchData();
+                }, this);
+                this.listenTo(this.searchCollection, 'error', function(data, key) {
+                    this.addJsonSearchData(key);
+                    this.hideLoader();
+                }, this);
+            },
+            onRender: function() {
+                this.bindEvents();
+                this.fetchCollections();
+            },
+            fetchCollections: function() {
+                this.asyncFetchCounter++;
+                if (this.guid) {
+                    this.collection.url = UrlLinks.entitiesApiUrl(this.guid);
+                    this.collection.fetch({ reset: true });
+                } else {
+                    this.collection.url = UrlLinks.entitiesDefApiUrl()
+                    this.collection.modelAttrName = 'list';
+                    this.collection.fetch({ reset: true });
+                }
+
+            },
+            entityCollectionList: function() {
+                this.ui.entityList.empty();
+                var that = this,
+                    name = "",
+                    value;
+                if (this.guid) {
+                    this.collection.each(function(val) {
+                        name += val.get("attributes").name || val.get("attributes").qualifiedName || val.get("attributes").id;
+                        that.entityData = val;
+                    });
+                    this.ui.assetName.html(name);
+                    this.onEntityChange(null, this.entityData);
+                } else {
+                    var str = '<option selected="selected" disabled="disabled">--Select entity-type--</option>';
+                    this.collection.fullCollection.comparator = function(model) {
+                        return model.get('name');
+                    }
+                    this.collection.fullCollection.sort().each(function(val) {
+                        str += '<option>' + val.get("name") + '</option>';
+                    });
+                    this.ui.entityList.html(str);
+                }
+            },
+            capitalize: function(string) {
+                return string.charAt(0).toUpperCase() + string.slice(1);
+            },
+            requiredAllToggle: function(checked) {
+                if (checked) {
+                    this.ui.entityInputData.find('div.true').show();
+                    this.ui.entityInputData.find('fieldset div.true').show();
+                    this.required = false;
+                } else {
+                    this.ui.entityInputData.find('div.true').hide();
+                    this.ui.entityInputData.find('fieldset div.true').hide();
+                    this.required = true;
+                }
+
+            },
+            onEntityChange: function(e, value) {
+                var that = this,
+                    typeName;
+                this.showLoader();
+                this.ui.entityInputData.empty();
+                if (value) {
+                    typeName = value.get("typeName");
+                }
+                if (typeName) {
+                    this.collection.url = UrlLinks.entitiesDefApiUrl(typeName);
+                } else {
+                    this.collection.url = UrlLinks.entitiesDefApiUrl(e.target.value);
+                    this.collection.modelAttrName = 'attributeDefs';
+                }
+                this.collection.fetch({
+                    success: function(model, data) {
+                        that.subAttributeData(data)
+                    },
+                    complete: function() {
+                        var _self = that;
+                        that.$('input[data-type="date"]').each(function() {
+                            if (!$(this).data('datepicker')) {
+                                $(this).datetimepicker({
+                                    format: 'DD MMMM YYYY'
+                                });
+                            }
+                        });
+                        that.$('input[data-type="long"]').each(function() {
+                            if (!$(this).data('datepicker')) {
+                                $(this).datetimepicker({
+                                    format: 'DD MMMM YYYY, HH:mm',
+                                    showTodayButton: true,
+                                    showClose: true
+                                });
+                            }
+                        });
+                        // 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] 
+                            if (!regex.test(e.currentTarget.value)) {
+                                return false;
+                            }
+                        });
+                        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);
+
+                        }
+                        // 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] 
+                            if (!regex.test(e.currentTarget.value)) {
+                                var txtfld = e.currentTarget;
+                                var newtxt = txtfld.value.slice(0, txtfld.value.length - 1);
+                                txtfld.value = newtxt;
+                            }
+                        });
+                    },
+                    silent: true
+                });
+            },
+            subAttributeData: function(data) {
+                var that = this,
+                    attributeInput = "",
+                    alloptional = false;
+                _.each(data.attributeDefs, function(value) {
+                    if (value.isOptional == true) {
+                        alloptional = true;
+                    }
+
+                    attributeInput += that.getContainer(value);
+                });
+                if (attributeInput !== "") {
+                    entityTitle = that.getFieldSet(data, alloptional, attributeInput);
+                    that.ui.entityInputData.prepend(entityTitle);
+                }
+                if (data.superTypes && data.superTypes.length > 0) {
+                    for (var j = 0; j < data.superTypes.length; j++) {
+                        var superTypeAttr = data.superTypes[j];
+                        that.fetchTagSubData(superTypeAttr);
+                    }
+                } else {
+                    this.hideLoader();
+                }
+                if (this.required) {
+                    this.ui.entityInputData.find('fieldset div.true').hide()
+                    this.ui.entityInputData.find('div.true').hide();
+                }
+                if (!('placeholder' in HTMLInputElement.prototype)) {
+                    this.ui.entityInputData.find('input,select,textarea').placeholder();
+                }
+            },
+            getContainer: function(value) {
+                var entityLabel = this.capitalize(value.name);
+                return '<div class="row row-margin-bottom ' + value.isOptional + '"><span class="col-md-3">' +
+                    '<label class="' + value.isOptional + '">' + entityLabel + (value.isOptional == true ? '' : ' <span class="requiredInput">*</span>') + '</label></span>' +
+                    '<span class="col-md-9 position-relative">' +
+                    (value.typeName === "boolean" ? this.getSelect(value) : this.getInput(value)) +
+                    '<span class="spanEntityType" title="Data Type : ' + value.typeName + '">' + '(' + Utils.escapeHtml(value.typeName) + ')' + '</span></input></span></div>';
+            },
+            getFieldSet: function(data, alloptional, attributeInput) {
+                return '<fieldset class="scheduler-border' + (alloptional ? " alloptional" : "") + '"><legend class="scheduler-border">' + data.name + '</legend>' + attributeInput + '</fieldset>';
+            },
+            getInput: function(value) {
+                var that = this;
+                var entityValue = "";
+                if (this.guid) {
+                    var dataValue = this.entityData.get("attributes")[value.name];
+                    if (_.isObject(dataValue)) {
+                        entityValue = JSON.stringify(dataValue);
+                    } else {
+                        if (dataValue) {
+                            entityValue = dataValue;
+                        }
+                        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") {
+                    return '<input class="form-control entityInputBox ' + (value.isOptional === true ? "false" : "true") + '"' +
+                        ' data-type="' + value.typeName + '"' +
+                        ' value="' + entityValue + '"' +
+                        ' data-key="' + value.name + '"' +
+                        ' placeholder="' + value.name + '"' +
+                        ' data-id="entityInput">';
+                } else if (value.typeName === "map<string,string>") {
+                    return '<textarea class="form-control entityInputBox ' + (value.isOptional === true ? "false" : "true") + '"' +
+                        ' data-type="' + value.typeName + '"' +
+                        ' data-key="' + value.name + '"' +
+                        ' placeholder="' + value.name + '"' +
+                        ' data-id="entityInput">' + entityValue + '</textarea>';
+                } else {
+                    var changeDatatype;
+                    if (value.typeName.indexOf("array") == -1) {
+                        changeDatatype = value.typeName;
+                    } else {
+                        if (value.typeName === "array<string>") {
+                            changeDatatype = value.typeName;
+                        } else {
+                            changeDatatype = value.typeName.split('<')[1].split('>')[0];
+                        }
+                    }
+                    $.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>';
+                }
+            },
+            getSelect: function(value) {
+                return '<select class="form-control row-margin-bottom ' + (value.isOptional === true ? "false" : "true") + '" data-type="' + value.typeName + '" data-key="' + value.name + '" data-id="entityInput">' +
+                    '<option disabled="disabled">--Select true or false--</option><option>true</option>' +
+                    '<option>false</option></select>';
+            },
+            fetchTagSubData: function(entityName) {
+                var that = this;
+                this.collection.url = UrlLinks.entitiesDefApiUrl(entityName);
+                this.collection.modelAttrName = 'attributeDefs';
+                this.asyncFetchCounter++;
+                this.collection.fetch({
+                    success: function(model, data) {
+                        that.subAttributeData(data);
+                    },
+                    complete: function() {
+                        --that.asyncFetchCounter;
+                        if (that.asyncFetchCounter === 0) {
+                            that.$('input[data-type="date"]').each(function() {
+                                if (!$(this).data('datepicker')) {
+                                    $(this).datetimepicker({
+                                        format: 'DD MMMM YYYY'
+                                    });
+                                }
+                            });
+                            that.$('input[data-type="long"]').each(function() {
+                                if (!$(this).data('datepicker')) {
+                                    $(this).datetimepicker({
+                                        format: 'DD MMMM YYYY, HH:mm',
+                                        showTodayButton: true,
+                                        showClose: true
+                                    });
+                                }
+                            });
+                            that.hideLoader();
+                        }
+                        that.$('select[data-type="boolean"]').each(function(value, key) {
+                            var dataKey = $(key).data('key');
+                            if (that.entityData) {
+                                var setValue = that.entityData.get("attributes")[dataKey];
+                                this.value = setValue;
+                            }
+                        });
+
+                    },
+                    silent: true
+                });
+            },
+
+            okButton: function() {
+                var that = this;
+                this.showLoader();
+                this.parentEntity = this.ui.entityList.val();
+                var entityAttribute = {};
+                that.validateError = false;
+                that.validateMessage = false;
+                this.ui.entityInputData.find("input,select,textarea").each(function() {
+                    var value = $(this).val();
+                    if ($(this).val() && $(this).val().trim) {
+                        value = $(this).val().trim();
+                    }
+                    if ($(this).hasClass("true")) {
+                        if (value == "" || value == undefined) {
+                            if ($(this).data('select2')) {
+                                $(this).data('select2').$container.addClass("errorClass")
+                            } else {
+                                $(this).addClass('errorClass');
+                            }
+                            that.hideLoader();
+                            that.validateError = true;
+                            that.validateMessage = true;
+                            return;
+                        }
+                    }
+                    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) {
+                        entityAttribute[datakeyEntity] = Date.parse($(this).val());
+                    } else if (dataTypeEnitity == "string" || dataTypeEnitity === "long" || dataTypeEnitity === "int" || dataTypeEnitity === "boolean" || dataTypeEnitity == "date") {
+                        entityAttribute[datakeyEntity] = $(this).val();
+                    } else {
+                        try {
+                            if (value !== undefined && value !== null && value !== "") {
+                                if (_.isArray(value)) {
+                                    var arrayEmptyValueCheck = value.join("")
+                                    if (arrayEmptyValueCheck === "") {
+                                        return;
+                                    }
+                                    if (dataTypeEnitity === "array<string>" || dataTypeEnitity === "map<string,string>") {
+                                        parseData = value;
+                                    } else {
+                                        if (that.selectStoreCollection.length) {
+                                            var parseData = value.map(function(val) {
+                                                var temp = {} // I9 support;
+                                                temp[pickKey] = val;
+                                                var valueData = that.selectStoreCollection.findWhere(temp).toJSON();
+                                                valueData['guid'] = valueData.id;
+                                                return valueData;
+                                            })
+                                        }
+                                    }
+                                } else {
+                                    if (that.selectStoreCollection.length && pickKey) {
+                                        var temp = {} // I9 support;
+                                        temp[pickKey] = $(this).val();
+                                        var parseData = that.selectStoreCollection.findWhere(temp).toJSON();
+                                        parseData['guid'] = parseData.id || parseData['$id$'].id;
+                                    }
+                                    // Object but maptype
+                                    if (!pickKey) {
+                                        parseData = JSON.parse($(this).val());
+                                    }
+                                }
+                                entityAttribute[datakeyEntity] = parseData
+                                $(this).removeClass('errorClass');
+                            }
+                        } catch (e) {
+                            $(this).addClass('errorClass');
+                            that.validateError = e;
+                            that.hideLoader();
+                        }
+                    }
+                });
+                var entityJson = {
+                    "typeName": this.guid ? this.entityData.get("typeName") : this.parentEntity,
+                    "attributes": entityAttribute
+                };
+                if (this.guid) {
+                    entityJson["guid"] = this.entityData.get("guid");
+                };
+                if (that.validateError) {
+                    if (that.validateMessage) {
+                        Utils.notifyError({
+                            content: "Please fill the required fields"
+                        });
+                    } else {
+                        Utils.notifyError({
+                            content: that.validateError.message
+                        });
+                    }
+                    that.validateError = null;
+                    that.hideLoader();
+                } else {
+                    this.entityModel.createOreditEntity(this.guid, {
+                        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']
+                            });
+                        },
+                        error: function(response) {
+                            if (response.responseJSON) {
+                                Utils.notifyError({
+                                    content: response.responseJSON.error || response.responseJSON.errorMessage
+                                });
+                            }
+                        },
+                        complete: function() {
+                            that.hideLoader();
+                        }
+                    });
+                }
+            },
+            showLoader: function() {
+                this.$('.entityLoader').show();
+                this.$('.entityInputData').hide();
+            },
+            hideLoader: function() {
+                this.$('.entityLoader').hide();
+                this.$('.entityInputData').show();
+            },
+            addJsonSearchData: function(isError) {
+                var that = this,
+                    typename,
+                    str = '';
+                if (isError) {
+                    typename = isError.responseJSON.error.split(": ")[1];
+                } else {
+                    if (this.searchCollection.length) {
+                        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";
+                            }
+                            str += '<option>' + value.get(labelName) + '</option>';
+                        });
+                    }
+                }
+                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) {
+                    var keyData = $(this).data("key");
+                    var typeData = $(this).data("type");
+                    var placeholderName = "Select a " + typename + " from the dropdown list";
+                    var $this = $(this);
+                    $this.attr("multiple", ($this.data('type').indexOf("array") === -1 ? false : true))
+                    if (that.guid) {
+                        if (that.selectStoreCollection.length) {
+                            var selectedValue = [];
+                        }
+                        var dataValue = that.entityData.get("attributes")[keyData];
+                        that.selectStoreCollection.each(function(value) {
+                            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"));
+                                    }
+                                });
+                            } else if (dataValue !== null) {
+                                if (dataValue.guid === value.get("id")) {
+                                    selectedValue.push(value.get("qualifiedName") || value.get("name") || value.get("id"));
+                                }
+                            }
+                        });
+                        if (selectedValue) {
+                            $this.val(selectedValue);
+                        } else {
+                            if (that.guid) {
+                                var dataValue = that.entityData.get("attributes")[keyData];
+                                if (dataValue !== null) {
+                                    _.each(dataValue, function(obj) {
+                                        str += '<option>' + obj + '</option>';
+                                    });
+                                    $this.html(str);
+                                }
+                            }
+                            $this.val(dataValue);
+                        }
+                    } else {
+                        $this.val("");
+                    }
+                    $this.select2({
+                        placeholder: placeholderName,
+                        allowClear: true,
+                        tags: true
+                    });
+                });
+            }
+        });
+    return CreateEntityLayoutView;
+});

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/edc4786b/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 d652aa4..2dd2549 100644
--- a/dashboardv2/public/js/views/search/SearchLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchLayoutView.js
@@ -42,7 +42,8 @@ define(['require',
                 searchBtn: '[data-id="searchBtn"]',
                 clearSearch: '[data-id="clearSearch"]',
                 typeLov: '[data-id="typeLOV"]',
-                refreshBtn: '[data-id="refreshBtn"]'
+                refreshBtn: '[data-id="refreshBtn"]',
+                createEntity: "[data-id='createEntity']",
             },
             /** ui events hash */
             events: function() {
@@ -63,6 +64,7 @@ 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;
             },
             /**
@@ -247,7 +249,20 @@ 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/edc4786b/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 0a37834..ded4e38 100644
--- a/dashboardv2/public/js/views/search/SearchResultLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchResultLayoutView.js
@@ -57,7 +57,8 @@ define(['require',
                 previousData: "[data-id='previousData']",
                 nextData: "[data-id='nextData']",
                 pageRecordText: "[data-id='pageRecordText']",
-                addAssignTag: "[data-id='addAssignTag']"
+                addAssignTag: "[data-id='addAssignTag']",
+                editEntityButton: "[data-id='editEntityButton']"
             },
 
             /** ui events hash */
@@ -107,6 +108,7 @@ define(['require',
                 };
                 events["click " + this.ui.nextData] = "onClicknextData";
                 events["click " + this.ui.previousData] = "onClickpreviousData";
+                events["click " + this.ui.editEntityButton] = "onClickEditEntity";
                 return events;
             },
             /**
@@ -450,6 +452,7 @@ define(['require',
                                     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-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;
                                 }
                             }
@@ -485,6 +488,7 @@ define(['require',
                                     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;
                                 }
                             }
@@ -667,6 +671,22 @@ define(['require',
                 });
                 this.previousClick = true;
                 this.fetchCollection();
+            },
+
+            onClickEditEntity: function(e) {
+                var that = this;
+                $(e.currentTarget).blur();
+                var guid = $(e.currentTarget).data('giud');
+                require([
+                    'views/entity/CreateEntityLayoutView'
+                ], function(CreateEntityLayoutView) {
+                    var view = new CreateEntityLayoutView({
+                        guid: guid,
+                        callback: function() {
+                            that.fetchCollection();
+                        }
+                    });
+                });
             }
         });
     return SearchResultLayoutView;


Mime
View raw message