Repository: atlas
Updated Branches:
  refs/heads/master 7f20ffbaf -> 19abdf68e


ATLAS-2512: updated lineage UI to edit classification propagation

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


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

Branch: refs/heads/master
Commit: 4ba39dcad7c9d46f9838aa5aa75162cddc5f2b6a
Parents: 7f20ffb
Author: pratik24mac <pratik2...@gmail.com>
Authored: Tue Apr 10 16:58:13 2018 +0530
Committer: Madhan Neethiraj <mad...@apache.org>
Committed: Mon Apr 16 14:18:04 2018 -0700

----------------------------------------------------------------------
 dashboardv2/public/css/scss/graph.scss          | 110 ++++++++++-
 dashboardv2/public/css/scss/override.scss       |  12 +-
 .../public/js/collection/VRelationshipList.js   |  59 ++++++
 dashboardv2/public/js/models/VRelationship.js   |  64 +++++++
 .../detail_page/DetailPageLayoutView_tmpl.html  |   8 +-
 .../templates/graph/LineageLayoutView_tmpl.html |   2 +-
 .../PropagationPropertyModalView_tmpl.html      |  52 +++++
 dashboardv2/public/js/utils/UrlLinks.js         |   8 +
 .../views/detail_page/DetailPageLayoutView.js   |  94 ++++-----
 .../public/js/views/graph/LineageLayoutView.js  |  54 ++++--
 .../js/views/graph/PropagationPropertyModal.js  | 192 +++++++++++++++++++
 11 files changed, 587 insertions(+), 68 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/atlas/blob/4ba39dca/dashboardv2/public/css/scss/graph.scss
----------------------------------------------------------------------
diff --git a/dashboardv2/public/css/scss/graph.scss 
b/dashboardv2/public/css/scss/graph.scss
index 2d7e8a3..5784095 100644
--- a/dashboardv2/public/css/scss/graph.scss
+++ b/dashboardv2/public/css/scss/graph.scss
@@ -79,6 +79,12 @@
     }
 }
 
+.edgePath {
+    .path {
+        cursor: pointer;
+    }
+}
+
 .overlay {}
 
 .link {
@@ -100,10 +106,45 @@
         overflow: auto;
         max-height: 300px;
     }
+    /* Creates a small triangle extender for the tooltip */
+    &:after {
+        box-sizing: border-box;
+        display: inline;
+        font-size: 10px;
+        width: 100%;
+        line-height: 1;
+        color: rgba(0, 0, 0, 0.8);
+        position: absolute;
+    }
+    /* Nrthward tooltips */
     &.n:after {
-        margin: -1px 0 0;
+        content: "\25BC";
+        margin: -1px 0 0 0;
         top: 100%;
         left: 0;
+        text-align: center;
+    }
+    /* Eastward tooltips */
+    &.e:after {
+        content: "\25C0";
+        margin: -4px 0 0 0;
+        top: 50%;
+        left: -8px;
+    }
+    /* Southward tooltips */
+    &.s:after {
+        content: "\25B2";
+        margin: 0 0 1px 0;
+        top: -8px;
+        left: 0;
+        text-align: center;
+    }
+    /* Westward tooltips */
+    &.w:after {
+        content: "\25B6";
+        margin: -4px 0 0 -1px;
+        top: 50%;
+        left: 100%;
     }
 }
 
@@ -118,10 +159,77 @@ g.type-TK>rect {
     right: 5px;
 }
 
+.graph-toolbar {
+    background-color: $white;
+    margin-bottom: 10px;
+    padding: 10px;
+}
+
 .legends {
     >i {
         >span {
             font-family: 'Source Sans Pro';
         }
     }
+}
+
+.lineage-box {
+    .lineage-edge-details {
+        position: absolute;
+        left: 0;
+        overflow: auto;
+        top: 0px;
+        max-height: 100%;
+        box-shadow: 4px 13px 14px -12px;
+        background: #e7e7e7;
+        transform: scaleX(0);
+        width: 200px;
+        transition: transform 0.3s ease-in;
+        &.open {
+            transform: scaleX(1);
+        }
+        .title {
+            background: black;
+            color: white;
+            padding: 10px;
+            padding-left: 17px;
+            margin-top: 0;
+            font-size: 14px;
+            .navigation-font {
+                font-family: sans-serif;
+                padding: 0px 5px;
+                color: #fb4200;
+            }
+        }
+        .close-details {
+            position: absolute;
+            top: 0;
+            color: white;
+            left: 0;
+            height: 21px;
+            width: 21px;
+            cursor: pointer;
+            font-size: 16px;
+        }
+        .propagation-list {
+            overflow: auto;
+            list-style-type: none;
+            list-style-position: outside;
+            padding-left: 30px;
+        }
+        .overlay {
+            position: absolute;
+            left: 0;
+            top: 0;
+            right: 0;
+            bottom: 0;
+            background: #d2d2d2b8;
+            z-index: 99;
+        }
+        ul>li {
+            word-wrap: break-word;
+            margin-bottom: 5px;
+            text-align: left;
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/atlas/blob/4ba39dca/dashboardv2/public/css/scss/override.scss
----------------------------------------------------------------------
diff --git a/dashboardv2/public/css/scss/override.scss 
b/dashboardv2/public/css/scss/override.scss
index e224393..c3ee8b1 100644
--- a/dashboardv2/public/css/scss/override.scss
+++ b/dashboardv2/public/css/scss/override.scss
@@ -414,9 +414,19 @@ div.columnmanager-dropdown-container {
     color: #626467;
     border: 1px solid black;
 }
+
 .text-center {
     text-align: center !important;
 }
-.margin-15{
+
+.margin-15 {
     margin: 15px 0px;
+}
+
+.padding-left-0 {
+    padding-left: 0px !important;
+}
+
+.fa-color {
+    color: $color_keppel_approx
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/atlas/blob/4ba39dca/dashboardv2/public/js/collection/VRelationshipList.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/collection/VRelationshipList.js 
b/dashboardv2/public/js/collection/VRelationshipList.js
new file mode 100644
index 0000000..0064f2e
--- /dev/null
+++ b/dashboardv2/public/js/collection/VRelationshipList.js
@@ -0,0 +1,59 @@
+/**
+ * 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',
+    'utils/Globals',
+    'collection/BaseCollection',
+    'models/VRelationship',
+    'utils/UrlLinks'
+], function(require, Globals, BaseCollection, VRelationship, UrlLinks) {
+    'use strict';
+    var VRelationshipList = BaseCollection.extend(
+        //Prototypal attributes
+        {
+            url: UrlLinks.baseURL,
+
+            model: VRelationship,
+
+            initialize: function() {
+                this.modelName = 'VRelationship';
+                this.modelAttrName = 'results';
+            },
+            getRelationship: function(id, options) {
+                var url = UrlLinks.relationshipApiUrl(id);
+
+                options = _.extend({
+                    contentType: 'application/json',
+                    dataType: 'json'
+                }, options);
+
+                return this.constructor.nonCrudOperation.call(this, url, 
'GET', options);
+            }
+        },
+        //Static Class Members
+        {
+            /**
+             * Table Cols to be passed to Backgrid
+             * UI has to use this as base and extend this.
+             *
+             */
+            tableCols: {}
+        }
+    );
+    return VRelationshipList;
+});

http://git-wip-us.apache.org/repos/asf/atlas/blob/4ba39dca/dashboardv2/public/js/models/VRelationship.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/models/VRelationship.js 
b/dashboardv2/public/js/models/VRelationship.js
new file mode 100644
index 0000000..de96ae2
--- /dev/null
+++ b/dashboardv2/public/js/models/VRelationship.js
@@ -0,0 +1,64 @@
+/**
+ * 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',
+    'utils/Globals',
+    'models/BaseModel',
+    'utils/UrlLinks'
+], function(require, Globals, VBaseModel, UrlLinks) {
+    'use strict';
+    var VRelationship = VBaseModel.extend({
+
+        urlRoot: UrlLinks.relationshipApiUrl(),
+
+        defaults: {},
+
+        serverSchema: {},
+
+        idAttribute: 'id',
+
+        initialize: function() {
+            this.modelName = 'VRelationship';
+        },
+        toString: function() {
+            return this.get('name');
+        },
+        /*************************
+         * Non - CRUD operations
+         *************************/
+
+        getRelationship: function(token, options) {
+            var url = UrlLinks.relationshipApiUrl(token);
+            options = _.extend({
+                contentType: 'application/json',
+                dataType: 'json'
+            }, options);
+
+            return this.constructor.nonCrudOperation.call(this, url, 'GET', 
options);
+        },
+        saveRelationship: function(options) {
+            var url = UrlLinks.relationshipApiUrl();
+            options = _.extend({
+                contentType: 'application/json',
+                dataType: 'json'
+            }, options);
+            return this.constructor.nonCrudOperation.call(this, url, 'PUT', 
options);
+        },
+    }, {});
+    return VRelationship;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/atlas/blob/4ba39dca/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 8fc67e0..a77ffc1 100644
--- a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
@@ -30,7 +30,7 @@
                 </button>
             </div>
         </div>
-         <div class="form-group" style="display: none;" 
data-id="propagatedTagDiv">
+        <div class="form-group" style="display: none;" 
data-id="propagatedTagDiv">
             <span class="control-label-sm-pr pull-left">Propagated 
Classifications:</span>
             <div class="pull-left" data-id="propagatedTagList">
             </div>
@@ -40,7 +40,7 @@
         <div class="col-sm-12 default-tab">
             <ul class="nav nav-tabs" data-id="tab-list">
                 <li role="properties" class="tab active"><a 
href="#tab-details" aria-controls="tab-details" role="tab" 
data-toggle="tab">Properties</a></li>
-                <li role="lineage" class="tab"><a href="#tab-lineage" 
aria-controls="tab-lineage" role="tab" data-toggle="tab">Lineage</a></li>
+                <li role="lineage" class="tab lineageGraph" 
style="display:none"><a href="#tab-lineage" aria-controls="tab-lineage" 
role="tab" data-toggle="tab">Lineage</a></li>
                 <li role="relationship" class="tab"><a 
href="#tab-relationship" aria-controls="tab-relationship" role="tab" 
data-toggle="tab">Relationships</a></li>
                 <li role="classification"><a href="#tab-tagTable" 
aria-controls="tab-tagTable" role="tab" 
data-toggle="tab">Classifications</a></li>
                 <li role="audit" class="tab"><a href="#tab-audit" 
aria-controls="tab-audit" role="tab" data-toggle="tab">Audits</a></li>
@@ -60,7 +60,7 @@
             </div>
         </div>
         <div id="tab-lineage" role="lineage" class="tab-pane animated fadeIn">
-            <div class="resize-graph animated" align="center" 
style="height:64vh;">
+            <div class="resizeGraph animated position-relative" align="center" 
style="height:64vh;">
                 <div id="r_lineageLayoutView">
                     <div class="fontLoader-relative">
                         <i class="fa fa-refresh fa-spin-custom"></i>
@@ -69,7 +69,7 @@
             </div>
         </div>
         <div id="tab-relationship" role="relationship" class="tab-pane 
animated fadeIn">
-            <div class="resize-graph animated" align="center" 
style="height:64vh;">
+            <div class="resizeGraph animated position-relative" align="center" 
style="height:64vh;">
                 <div id="r_relationshipLayoutView">
                     <div class="fontLoader-relative">
                         <i class="fa fa-refresh fa-spin-custom"></i>

http://git-wip-us.apache.org/repos/asf/atlas/blob/4ba39dca/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html 
b/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html
index a94284b..096fb5b 100644
--- a/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/graph/LineageLayoutView_tmpl.html
@@ -15,7 +15,7 @@
  * limitations under the License.
 -->
 <!-- <div class="graph-toolbar clearfix"></div> -->
-<div style="position: absolute;height:100%;width:100%;" class="white-bg 
no-padding">
+<div style="position: absolute;height:100%;width:100%;" class="white-bg 
no-padding lineage-box">
     <div class="fontLoader">
         <i class="fa fa-refresh fa-spin-custom"></i>
     </div>

http://git-wip-us.apache.org/repos/asf/atlas/blob/4ba39dca/dashboardv2/public/js/templates/graph/PropagationPropertyModalView_tmpl.html
----------------------------------------------------------------------
diff --git 
a/dashboardv2/public/js/templates/graph/PropagationPropertyModalView_tmpl.html 
b/dashboardv2/public/js/templates/graph/PropagationPropertyModalView_tmpl.html
new file mode 100644
index 0000000..1599858
--- /dev/null
+++ 
b/dashboardv2/public/js/templates/graph/PropagationPropertyModalView_tmpl.html
@@ -0,0 +1,52 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<div class="lineage-edge-details" data-id="PropagationToolTip">
+    <h4 class="title"><span data-id="edgeDetailName"></span></h4>
+    <div class="overlay show">
+        <div class="fontLoader show">
+            <i class="fa fa-refresh fa-spin-custom"></i>
+        </div>
+    </div>
+    <div class="col-md-12">
+        <ul data-id="propagationOptions" class="propagation-list">
+            <li>
+                <div class="radio">
+                    <input type="radio" name="propagateRelation" 
value="ONE_TO_TWO" id="ONE_TO_TWO">
+                    <label class="padding-left-0" for="ONE_TO_TWO">ONE TO 
TWO</label>
+                </div>
+            </li>
+            <li>
+                <div class="radio">
+                    <input type="radio" name="propagateRelation" 
value="TWO_TO_ONE" id="TWO_TO_ONE">
+                    <label class="padding-left-0" for="TWO_TO_ONE">TWO TO 
ONE</label>
+                </div>
+            </li>
+            <li>
+                <div class="radio">
+                    <input type="radio" name="propagateRelation" value="BOTH" 
id="BOTH">
+                    <label class="padding-left-0" for="BOTH">BOTH</label>
+                </div>
+            </li>
+            <li>
+                <div class="radio">
+                    <input type="radio" name="propagateRelation" value="NONE" 
id="NONE">
+                    <label class="padding-left-0" for="NONE">None</label>
+                </div>
+            </li>
+        </ul>
+    </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/atlas/blob/4ba39dca/dashboardv2/public/js/utils/UrlLinks.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/UrlLinks.js 
b/dashboardv2/public/js/utils/UrlLinks.js
index b69e3a8..b9f3805 100644
--- a/dashboardv2/public/js/utils/UrlLinks.js
+++ b/dashboardv2/public/js/utils/UrlLinks.js
@@ -88,6 +88,14 @@ define(['require', 'utils/Enums', 'utils/Utils', 
'underscore'], function(require
                 return lineageUrl
             }
         },
+        relationshipApiUrl: function(guid) {
+            var relationshipUrl = this.baseUrlV2 + '/relationship';
+            if (guid) {
+                return relationshipUrl + '/guid/' + guid;
+            } else {
+                return relationshipUrl
+            }
+        },
         schemaApiUrl: function(guid) {
             var lineageUrl = this.baseUrl + '/lineage';
             if (guid) {

http://git-wip-us.apache.org/repos/asf/atlas/blob/4ba39dca/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 7c0cd55..99e9602 100644
--- a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
+++ b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
@@ -171,6 +171,7 @@ define(['require',
                         }
                     }
                     this.hideLoader();
+                    this.activeEntityDef = 
this.entityDefCollection.fullCollection.find({ name: collectionJSON.typeName });
                     var obj = {
                         entity: collectionJSON,
                         guid: this.id,
@@ -202,13 +203,30 @@ define(['require',
                     }
 
                     // To render Schema check attribute 
"schemaElementsAttribute"
-                    var schemaOptions = 
this.entityDefCollection.fullCollection.find({ name: collectionJSON.typeName 
}).get('options');
+                    var schemaOptions = this.activeEntityDef.get('options');
                     if (schemaOptions && 
schemaOptions.hasOwnProperty('schemaElementsAttribute') && 
schemaOptions.schemaElementsAttribute !== "") {
                         this.$('.schemaTable').show();
                         this.renderSchemaLayoutView(_.extend({}, obj, {
                             attribute: 
collectionJSON.attributes[schemaOptions.schemaElementsAttribute]
                         }));
                     }
+                    if (this.activeEntityDef && 
_.contains(this.activeEntityDef.get('superTypes'), "DataSet")) {
+                        this.$('.lineageGraph').show();
+                        this.renderLineageLayoutView({
+                            guid: this.id,
+                            entityDefCollection: this.entityDefCollection,
+                            actionCallBack: function() {
+                                that.$('#expand_collapse_panel').click();
+                            }
+                        });
+                        this.$(".resizeGraph").resizable({
+                            handles: ' s',
+                            minHeight: 375,
+                            stop: function(event, ui) {
+                                ui.element.height(($(this).height()));
+                            },
+                        });
+                    }
                 }, this);
                 this.listenTo(this.collection, 'error', function(model, 
response) {
                     this.$('.fontLoader-relative').removeClass('show');
@@ -223,43 +241,29 @@ define(['require',
                 var that = this;
                 Utils.showTitleLoader(this.$('.page-title .fontLoader'), 
this.$('.entityDetail'));
                 this.$('.fontLoader-relative').addClass('show'); // to show 
tab loader
-                this.renderLineageLayoutView({
-                    guid: this.id,
-                    entityDefCollection: this.entityDefCollection,
-                    actionCallBack: function() {
-                        that.$('#expand_collapse_panel').click();
-                    }
-                });
-                this.$(".resize-graph").resizable({
-                    handles: ' s',
-                    minHeight: 375,
-                    stop: function(event, ui) {
-                        that.$('.resize-graph').height(($(this).height()));
-                    },
-                });
-                this.ui.fullscreenPanel.on('fullscreen_done', function(e, 
panel) {
-                    var svgEl = panel.find('.panel-body svg'),
-                        scaleEl = svgEl.find('>g'),
-                        zoom = that.RLineageLayoutView.currentView.zoom,
-                        svg = that.RLineageLayoutView.currentView.svg,
-                        viewThis = that.RLineageLayoutView.currentView,
-                        setGraphZoomPositionCal = 
that.RLineageLayoutView.currentView.setGraphZoomPositionCal,
-                        zoomed = that.RLineageLayoutView.currentView.zoomed;;
+                // this.ui.fullscreenPanel.on('fullscreen_done', function(e, 
panel) {
+                //     var svgEl = panel.find('.panel-body svg'),
+                //         scaleEl = svgEl.find('>g'),
+                //         zoom = that.RLineageLayoutView.currentView.zoom,
+                //         svg = that.RLineageLayoutView.currentView.svg,
+                //         viewThis = that.RLineageLayoutView.currentView,
+                //         setGraphZoomPositionCal = 
that.RLineageLayoutView.currentView.setGraphZoomPositionCal,
+                //         zoomed = 
that.RLineageLayoutView.currentView.zoomed;;
 
-                    if (zoom) {
-                        setGraphZoomPositionCal.call(viewThis);
-                        zoomed.call(viewThis);
-                        if ($(e.currentTarget).find('i').hasClass('fa 
fa-compress')) {
-                            svg.call(zoom)
-                                .on("dblclick.zoom", null);
+                //     if (zoom) {
+                //         setGraphZoomPositionCal.call(viewThis);
+                //         zoomed.call(viewThis);
+                //         if ($(e.currentTarget).find('i').hasClass('fa 
fa-compress')) {
+                //             svg.call(zoom)
+                //                 .on("dblclick.zoom", null);
 
-                        } else {
-                            svg.call(zoom)
-                                .on("wheel.zoom", null)
-                                .on("dblclick.zoom", null);
-                        }
-                    }
-                })
+                //         } else {
+                //             svg.call(zoom)
+                //                 .on("wheel.zoom", null)
+                //                 .on("dblclick.zoom", null);
+                //         }
+                //     }
+                // })
             },
             onShow: function() {
                 var params = Utils.getUrlState.getQueryParams();
@@ -278,13 +282,17 @@ define(['require',
                 this.collection.fetch({ reset: true });
             },
             getEntityDef: function(entityObj) {
-                var data = this.entityDefCollection.fullCollection.findWhere({ 
name: entityObj.typeName }).toJSON();
-                var attributeDefs = Utils.getNestedSuperTypeObj({
-                    data: data,
-                    attrMerge: true,
-                    collection: this.entityDefCollection
-                });
-                return attributeDefs;
+                if (this.activeEntityDef) {
+                    var data = this.activeEntityDef.toJSON();
+                    var attributeDefs = Utils.getNestedSuperTypeObj({
+                        data: data,
+                        attrMerge: true,
+                        collection: this.entityDefCollection
+                    });
+                    return attributeDefs;
+                } else {
+                    return [];
+                }
             },
             onClickTagCross: function(e) {
                 var tagName = $(e.currentTarget).parent().text(),

http://git-wip-us.apache.org/repos/asf/atlas/blob/4ba39dca/dashboardv2/public/js/views/graph/LineageLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/graph/LineageLayoutView.js 
b/dashboardv2/public/js/views/graph/LineageLayoutView.js
index 25e7120..c1d8a9c 100644
--- a/dashboardv2/public/js/views/graph/LineageLayoutView.js
+++ b/dashboardv2/public/js/views/graph/LineageLayoutView.js
@@ -25,8 +25,9 @@ define(['require',
     'dagreD3',
     'd3-tip',
     'utils/Enums',
-    'utils/UrlLinks'
-], function(require, Backbone, LineageLayoutViewtmpl, VLineageList, VEntity, 
Utils, dagreD3, d3Tip, Enums, UrlLinks) {
+    'utils/UrlLinks',
+    'platform'
+], function(require, Backbone, LineageLayoutViewtmpl, VLineageList, VEntity, 
Utils, dagreD3, d3Tip, Enums, UrlLinks, platform) {
     'use strict';
 
     var LineageLayoutView = Backbone.Marionette.LayoutView.extend(
@@ -56,15 +57,17 @@ define(['require',
              */
             initialize: function(options) {
                 _.extend(this, _.pick(options, 'guid', 'entityDefCollection', 
'actionCallBack'));
-                this.entityModel = new VEntity();
                 this.collection = new VLineageList();
+                this.lineageData = null;
                 this.typeMap = {};
+                this.apiGuid = {};
                 this.asyncFetchCounter = 0;
-                this.fetchGraphData();
+                this.edgeCall;
             },
             onRender: function() {
                 var that = this;
                 this.$('.fontLoader').show();
+                this.fetchGraphData();
                 if (this.layoutRendered) {
                     this.layoutRendered();
                 }
@@ -90,12 +93,14 @@ define(['require',
                     skipDefaultError: true,
                     success: function(data) {
                         if (data.relations.length) {
+                            that.lineageData = data;
                             that.generateData(data.relations, 
data.guidEntityMap);
                         } else {
                             that.noLineage();
                         }
                     },
                     cust_error: function(model, response) {
+                        that.lineageData = [];
                         that.noLineage();
                     }
                 })
@@ -103,7 +108,7 @@ define(['require',
             noLineage: function() {
                 this.$('.fontLoader').hide();
                 //this.$('svg').height('100');
-                this.$('svg').html('<text x="' + (this.$('svg').width() - 150) 
/ 2 + '" y="' + this.$('svg').height() / 2 + '" fill="black">No lineage data 
found</text>');
+                this.$('svg').html('<text x="50%" y="50%" 
alignment-baseline="middle" text-anchor="middle">No lineage data found</text>');
                 if (this.actionCallBack) {
                     this.actionCallBack();
                 }
@@ -142,9 +147,10 @@ define(['require',
                     }
                     var styleObj = {
                         fill: 'none',
-                        stroke: '#8bc152'
+                        stroke: '#8bc152',
+                        width: 2
                     }
-                    that.g.setEdge(obj.fromEntityId, obj.toEntityId, { 
'arrowhead': "arrowPoint", lineInterpolate: 'basis', "style": "fill:" + 
styleObj.fill + ";stroke:" + styleObj.stroke + "", 'styleObj': styleObj });
+                    that.g.setEdge(obj.fromEntityId, obj.toEntityId, { 
'arrowhead': "arrowPoint", lineInterpolate: 'basis', "style": "fill:" + 
styleObj.fill + ";stroke:" + styleObj.stroke + ";stroke-width:" + 
styleObj.width + "", 'styleObj': styleObj });
                 });
 
                 if (this.fromToObj[this.guid]) {
@@ -180,17 +186,19 @@ define(['require',
                     scaleEl = this.$('svg').find('>g'),
                     translateValue = [(this.$('svg').width() - 
this.g.graph().width * initialScale) / 2, (this.$('svg').height() - 
this.g.graph().height * initialScale) / 2]
                 if (_.keys(this.g._nodes).length > 15) {
-                    translateValue = [((this.$('svg').width() / 2)) / 2, 20];
                     initialScale = 0;
                     this.$('svg').addClass('noScale');
                 }
-                if (svgEl.parents('.panel.panel-fullscreen').length && 
svgEl.hasClass('noScale')) {
-                    if (!scaleEl.hasClass('scaleLinage')) {
-                        scaleEl.addClass('scaleLinage');
-                        initialScale = 1.2;
-                    } else {
-                        scaleEl.removeClass('scaleLinage');
-                        initialScale = 0;
+                if (svgEl.parents('.panel.panel-fullscreen').length) {
+                    translateValue = [20, 20];
+                    if (svgEl.hasClass('noScale')) {
+                        if (!scaleEl.hasClass('scaleLinage')) {
+                            scaleEl.addClass('scaleLinage');
+                            initialScale = 1.2;
+                        } else {
+                            scaleEl.removeClass('scaleLinage');
+                            initialScale = 0;
+                        }
                     }
                 } else {
                     scaleEl.removeClass('scaleLinage');
@@ -344,7 +352,7 @@ define(['require',
                 d3.selectAll(this.$('span.lineageZoomButton')).on('click', 
zoomClick);
                 var tooltip = d3Tip()
                     .attr('class', 'd3-tip')
-                    .offset([-18, 0])
+                    .offset([10, 0])
                     .html(function(d) {
                         var value = that.g.node(d);
                         var htmlStr = "";
@@ -363,7 +371,6 @@ define(['require',
 
                 svg.call(zoom)
                     .call(tooltip);
-                this.$('.fontLoader').hide();
                 render(svgGroup, this.g);
                 svg.on("dblclick.zoom", null)
                     .on("wheel.zoom", null);
@@ -414,6 +421,18 @@ define(['require',
                             }
                         }, 400)
                     });
+                svgGroup.selectAll("g.edgePath path.path").on('click', 
function(d) {
+                    var data = { obj: _.find(that.lineageData.relations, { 
"fromEntityId": d.v, "toEntityId": d.w }) },
+                        relationshipId = data.obj.relationshipId;
+                    require(['views/graph/PropagationPropertyModal'], 
function(PropagationPropertyModal) {
+                        var view = new PropagationPropertyModal({
+                            edgeInfo: data,
+                            relationshipId: relationshipId,
+                            lineageData: that.lineageData,
+                            apiGuid: that.apiGuid
+                        });
+                    });
+                })
                 $('body').on('mouseover', '.d3-tip', function(el) {
                     that.activeTip = true;
                 });
@@ -427,7 +446,6 @@ define(['require',
                 this.setGraphZoomPositionCal();
                 zoom.event(svg);
                 //svg.attr('height', this.g.graph().height * initialScale + 
40);
-
             }
         });
     return LineageLayoutView;

http://git-wip-us.apache.org/repos/asf/atlas/blob/4ba39dca/dashboardv2/public/js/views/graph/PropagationPropertyModal.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/graph/PropagationPropertyModal.js 
b/dashboardv2/public/js/views/graph/PropagationPropertyModal.js
new file mode 100644
index 0000000..c192dff
--- /dev/null
+++ b/dashboardv2/public/js/views/graph/PropagationPropertyModal.js
@@ -0,0 +1,192 @@
+/**
+ * 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',
+    'hbs!tmpl/graph/PropagationPropertyModalView_tmpl',
+    'models/VRelationship',
+    'modules/Modal',
+    'utils/Utils',
+    'utils/UrlLinks',
+    'utils/Messages'
+], function(require, PropagationPropertyModalViewTmpl, VRelationship, Modal, 
Utils, UrlLinks, Messages) {
+    'use strict';
+
+    var PropogationPropertyModal = Backbone.Marionette.CompositeView.extend({
+        template: PropagationPropertyModalViewTmpl,
+        templateHelpers: function() {},
+        regions: {},
+        ui: {
+            propagationOptions: '[data-id="propagationOptions"]',
+            edgeDetailName: '[data-id="edgeDetailName"]'
+        },
+        events: function() {
+            var events = {};
+            events["change " + this.ui.propagationOptions] = function() {
+                this.modal.$el.find('button.ok').attr("disabled", false);
+            };
+            return events;
+        },
+        /**
+         * intialize a new PropogationPropertyModal Layout
+         * @constructs
+         */
+        initialize: function(options) {
+            _.extend(this, _.pick(options, 'edgeInfo', 'relationshipId', 
'lineageData', 'apiGuid'));
+            this.entityModel = new VRelationship();
+            var that = this,
+                modalObj = {
+                    title: 'Edit Propagation Flow',
+                    content: this,
+                    okText: 'Update',
+                    okCloses: false,
+                    cancelText: "Cancel",
+                    mainClass: 'modal-md',
+                    allowCancel: true,
+                };
+
+            this.modal = new Modal(modalObj)
+            this.modal.open();
+            this.modal.$el.find('button.ok').attr("disabled", true);
+            this.on('ok', function() {
+                that.updateRelation();
+            });
+            this.on('closeModal', function() {
+                this.modal.trigger('cancel');
+            });
+            this.updateEdgeView(this.edgeInfo);
+        },
+
+        onRender: function() {
+
+        },
+        updateEdgeView: function(options) {
+            var obj = options.obj,
+                fromEntity = this.lineageData.guidEntityMap[obj.fromEntityId],
+                toEntity = this.lineageData.guidEntityMap[obj.toEntityId];
+            if (fromEntity && toEntity) {
+                this.ui.edgeDetailName.html(fromEntity.displayText + " <span 
class='navigation-font'><i class='fa fa-long-arrow-right fa-color'></i></span> 
" + toEntity.displayText);
+            }
+            if (obj && obj.relationshipId) {
+                this.showLoader();
+                this.getEdgeEntity({ id: obj.relationshipId, from: fromEntity, 
to: toEntity });
+            }
+        },
+        getPropagationFlow: function(options) {
+            var relationshipData = options.relationshipData,
+                graphData = options.graphData,
+                propagateTags = relationshipData.propagateTags;
+            if (relationshipData.end1) {
+                if (relationshipData.end1.guid == graphData.from.guid || 
propagateTags == "BOTH" || propagateTags == "NONE") {
+                    return propagateTags;
+                } else {
+                    return propagateTags == "ONE_TO_TWO" ? "TWO_TO_ONE" : 
"ONE_TO_TWO";
+                }
+            } else {
+                return propagateTags;
+            }
+        },
+        getEdgeEntity: function(options) {
+            var that = this,
+                id = options.id,
+                from = options.from,
+                to = options.to,
+                icon = {
+                    0: 'fa-long-arrow-right',
+                    1: 'fa-long-arrow-left',
+                    2: 'fa-arrows-h'
+                };
+            _.each(icon, function(value, key) {
+                that.ui.propagationOptions.find('li label')[key].innerHTML = 
from.typeName + ' <i class="fa-color fa ' + value + '"></i> ' + to.typeName;
+            });
+            if (id === this.ui.propagationOptions.attr("entity-id")) {
+                return;
+            }
+            this.ui.propagationOptions.attr("entity-id", id);
+            if (this.apiGuid[id]) {
+                this.hideLoader();
+                
this.$("input[name='propagateRelation']").removeAttr('checked');
+                this.$("input[name='propagateRelation'][value=" + 
that.getPropagationFlow({
+                    "relationshipData": this.apiGuid[id],
+                    "graphData": options
+                }) + "]").prop('checked', true);
+            } else {
+                if (this.edgeCall && this.edgeCall.readyState != 4) {
+                    this.edgeCall.abort();
+                }
+                this.edgeCall = this.entityModel.getRelationship(id, {
+                    success: function(relationshipData) {
+                        if (relationshipData) {
+                            that.apiGuid[relationshipData.guid] = 
relationshipData;
+                            
that.$("input[name='propagateRelation']").removeAttr('checked');
+                            that.$("input[name='propagateRelation'][value=" + 
that.getPropagationFlow({
+                                "relationshipData": relationshipData,
+                                "graphData": options
+                            }) + "]").prop('checked', true);
+                            that.hideLoader({ buttonDisabled: true });
+                        }
+                    },
+                    cust_error: function() {
+                        that.hideLoader();
+                    }
+                });
+            }
+        },
+        updateRelation: function() {
+            var that = this,
+                entityId = that.ui.propagationOptions.attr('entity-id'),
+                PropagationValue = 
this.$("input[name='propagateRelation']:checked").val();
+            if (PropagationValue === 
this.ui.propagationOptions.attr("propagation")) {
+                return;
+            }
+            this.ui.propagationOptions.attr("propagation", PropagationValue);
+            var relationshipProp = {
+                "propagateTags": that.getPropagationFlow({
+                    "relationshipData": that.apiGuid[entityId],
+                    "graphData": { from: { guid: 
this.edgeInfo.obj.fromEntityId } }
+                })
+            };
+            this.showLoader();
+            this.entityModel.saveRelationship({
+                data: JSON.stringify(_.extend(that.apiGuid[entityId], 
relationshipProp)),
+                success: function(relationshipData) {
+                    if (relationshipData) {
+                        that.hideLoader({ buttonDisabled: true });
+                        that.modal.trigger('cancel');
+                        that.apiGuid[relationshipData.guid] = relationshipData;
+                        Utils.notifySuccess({
+                            content: "Propagation flow updated succesfully."
+                        });
+                    }
+                },
+                cust_error: function() {
+                    that.hideLoader();
+                }
+            });
+        },
+        showLoader: function() {
+            this.modal.$el.find('button.ok').attr("disabled", true);
+            this.$('.overlay').removeClass('hide').addClass('show');
+        },
+        hideLoader: function(options) {
+            var buttonDisabled = options && options.buttonDisabled;
+            this.modal.$el.find('button.ok').attr("disabled", buttonDisabled ? 
buttonDisabled : false);
+            this.$('.overlay').removeClass('show').addClass('hide');
+        }
+    });
+    return PropogationPropertyModal;
+});
\ No newline at end of file

Reply via email to