atlas-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kbh...@apache.org
Subject [1/2] incubator-atlas git commit: ATLAS-1287 Subtasks: ATLAS-1288/ATLAS-1289 Integrated V2 API for Lineage, Entity Details, Tag assign to entity, Tags listing, tag create
Date Wed, 14 Dec 2016 05:40:28 GMT
Repository: incubator-atlas
Updated Branches:
  refs/heads/master 3bffc0dcc -> efc8d09c8


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/efc8d09c/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 eebbd9f..d16674e 100644
--- a/dashboardv2/public/js/views/graph/LineageLayoutView.js
+++ b/dashboardv2/public/js/views/graph/LineageLayoutView.js
@@ -24,9 +24,10 @@ define(['require',
     'utils/Utils',
     'dagreD3',
     'd3-tip',
-    'utils/Globals',
+    'utils/Enums',
+    'utils/UrlLinks',
     'jquery-ui'
-], function(require, Backbone, LineageLayoutViewtmpl, VLineageList, VEntity, Utils, dagreD3, d3Tip, Globals) {
+], function(require, Backbone, LineageLayoutViewtmpl, VLineageList, VEntity, Utils, dagreD3, d3Tip, Enums, UrlLinks) {
     'use strict';
 
     var LineageLayoutView = Backbone.Marionette.LayoutView.extend(
@@ -56,32 +57,11 @@ define(['require',
              */
             initialize: function(options) {
                 _.extend(this, _.pick(options, 'globalVent', 'guid'));
-                this.inputCollection = new VLineageList();
-                this.outputCollection = new VLineageList();
                 this.entityModel = new VEntity();
-                this.inputCollection.url = "/api/atlas/lineage/" + this.guid + "/inputs/graph";
-                this.outputCollection.url = "/api/atlas/lineage/" + this.guid + "/outputs/graph";
-                this.bindEvents();
-                this.fetchGraphData();
-                this.data = {};
+                this.collection = new VLineageList();
+                this.typeMap = {};
                 this.asyncFetchCounter = 0;
-
-            },
-            bindEvents: function() {
-                this.listenTo(this.inputCollection, 'reset', function() {
-                    this.generateData(this.inputCollection, 'input');
-                    this.outputCollection.fetch({ reset: true });
-                }, this);
-                this.listenTo(this.outputCollection, 'reset', function() {
-                    this.generateData(this.outputCollection, 'output');
-                    this.outputState = true;
-                }, this);
-                this.listenTo(this.outputCollection, 'error', function() {
-                    this.addNoDataMessage();
-                }, this);
-                this.listenTo(this.inputCollection, 'error', function() {
-                    this.addNoDataMessage();
-                }, this);
+                this.fetchGraphData();
             },
             onRender: function() {
                 var that = this;
@@ -109,179 +89,94 @@ define(['require',
                     });
             },
             fetchGraphData: function() {
-                this.inputCollection.fetch({ reset: true });
+                var that = this;
+                this.fromToObj = {};
+                this.collection.getLineage(this.guid, {
+                    success: function(data) {
+                        if (data.relations.length) {
+                            that.generateData(data.relations, data.guidEntityMap);
+                        } else {
+                            that.noLineage();
+                        }
+                    },
+                    error: function(error, data, status) {
+                        that.noLineage();
+                    },
+                    complete: function() {}
+                })
             },
-            addNoDataMessage: function() {
-                //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>');
+            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>');
             },
-            generateData: function(collection, type) {
+            generateData: function(relations, guidEntityMap) {
                 var that = this;
 
-                function addValueInObject(data) {
-                    var obj = {};
-                    if (data && data.definition) {
-                        if (data.definition.values) {
-                            var values = data.definition.values;
-                            obj['label'] = values.name;
-
-                            obj['toolTiplabel'] = values.name;
-                            if (data.definition.typeName) {
-                                var temp = obj['label'] + ' (' + data.definition.typeName + ')'
-                                obj['label'] = temp;
-                                obj['toolTiplabel'] = temp;
-                            }
-                            obj['label'] = obj['label'].trunc(18);
-                            obj['id'] = data.GUID;
-                            if (values.queryText) {
-                                obj['queryText'] = values.queryText;
-                            }
-                            if (data.definition.id && data.definition.id.state) {
-                                obj['state'] = data.definition.id.state;
-                            }
-                        }
-                    } else {
-                        obj['label'] = ""
-                        obj['toolTiplabel'] = "";
-                    }
-                    obj['shape'] = "img";
-                    obj['class'] = "type-TOP";
-                    if (data.GUID) {
-                        that.g.setNode(data.GUID, obj);
-                    } else {
-                        if (data && data.definition) {
-                            if (_.isString(data.definition.id)) {
-                                that.g.setNode(data.definition.id, obj);
-                            } else if (_.isString(data.definition.id.id)) {
-                                that.g.setNode(data.definition.id.id, obj);
-                            }
-                        }
-                    }
-                    --that.asyncFetchCounter;
-                    if (that.asyncFetchCounter === 0) {
-                        if (that.edgesAndvertices) {
-                            that.createGraph(that.edgesAndvertices, that.startingPoint);
-                        } else if (this.outputState && !that.edgesAndvertices) {
-                            that.addNoDataMessage();
-                        }
-                    }
-                }
-
-                function fetchLoadProcess(id) {
+                function fetchEntity(name) {
                     ++that.asyncFetchCounter;
-                    that.entityModel.getEntity(id, {
+                    that.entityModel.getEntityDef(name, {
                         success: function(data) {
-                            addValueInObject(data);
-                        },
-                        error: function(error, data, status) {},
-                        complete: function() {}
-                    });
-                }
-
-                function makeNode(c) {
-                    var edges = c.edges,
-                        vertices = c.vertices,
-                        allKeys = [];
-                    _.each(c.edges, function(val, key, obj) {
-                        allKeys.push(key);
-                        _.each(val, function(val1, key1, obj1) {
-                            allKeys.push(val1);
-                        });
-                    });
-                    var uniquNode = _.uniq(allKeys);
-                    _.each(uniquNode, function(val, key) {
-                        var obj = {};
-                        if (vertices[val] && vertices[val].values) {
-                            obj['label'] = vertices[val].values.name;
-                            obj['toolTiplabel'] = vertices[val].values.name;
-                            if (vertices[val].values.vertexId && vertices[val].values.vertexId.values && vertices[val].values.vertexId.values.typeName) {
-                                var temp = obj['label'] + ' (' + vertices[val].values.vertexId.values.typeName + ')';
-                                obj['label'] = temp;
-                                obj['toolTiplabel'] = temp;
-                            }
-                            obj['label'] = obj['label'].trunc(18);
-                            obj['id'] = val;
-                            obj['class'] = "type-TOP";
-                            obj['shape'] = "img";
-                            obj['typeName'] = vertices[val].values.vertexId.values.typeName;
-                            if (vertices[val].values.state) {
-                                obj['state'] = vertices[val].values.state;
-                            } else if (vertices[val].values.vertexId.values.state) {
-                                obj['state'] = vertices[val].values.vertexId.values.state;
+                            if (that.typeMap[data.name]) {
+                                _.keys(that.fromToObj).map(function(key) {
+                                    var obj = that.fromToObj[key];
+                                    if (obj.typeName === data.name) {
+                                        that.fromToObj[key]['isProcess'] = _.contains(data.superTypes, "Process") ? true : false;
+                                    }
+                                });
                             }
-                            if (val && obj) {
-                                that.g.setNode(val, obj);
+                            that.typeMap[data.name] = data.superTypes;
+                        },
+                        complete: function() {
+                            --that.asyncFetchCounter;
+                            if (that.asyncFetchCounter == 0) {
+                                that.createGraph();
                             }
-                        } else {
-                            fetchLoadProcess(val);
                         }
                     });
                 }
-                _.each(collection.models, function(values) {
-                    var valuObj = values.get('values');
-                    that.startingPoint = [];
-                    if (!_.isEmpty(valuObj.edges)) {
-                        if (type == "input") {
-                            that.edgesAndvertices = {
-                                edges: {},
-                                vertices: valuObj.vertices
-                            };
-                            _.each(valuObj.edges, function(val, key, obj) {
-                                _.each(val, function(val1, key1, obj1) {
-                                    if (!obj[val1]) {
-                                        that.startingPoint.push(val1);
-                                    }
-                                    if (that.edgesAndvertices.edges[val1]) {
-                                        that.edgesAndvertices.edges[val1].push(key);
-                                    } else {
-                                        that.edgesAndvertices.edges[val1] = [key];
-                                    }
-                                });
-                            });
-                        } else {
-                            that.edgesAndvertices = valuObj;
-                            that.startingPoint = [that.guid];
-                        }
-                        makeNode(that.edgesAndvertices);
-                    } else {
-                        if (type == 'output') {
-                            that.outputState = true;
-                        }
+
+                function makeNodeObj(relationObj) {
+                    var obj = {};
+                    obj['shape'] = "img";
+                    obj['typeName'] = relationObj.typeName
+                    obj['label'] = relationObj.displayText.trunc(18);
+                    obj['toolTiplabel'] = relationObj.displayText;
+                    if (obj.typeName) {
+                        var temp = obj['label'] + ' (' + relationObj.typeName + ')';
+                        obj['toolTiplabel'] = temp
+                        obj['label'] = temp.trunc(18);
                     }
-                });
-                if (this.asyncFetchCounter <= 0) {
-                    if (this.edgesAndvertices) {
-                        this.createGraph(that.edgesAndvertices, this.startingPoint);
-                    } else if (this.outputState && !this.edgesAndvertices) {
-                        this.$('.fontLoader').hide();
-                        that.$('svg').height('100');
-                        that.$('svg').html('<text x="' + (that.$('svg').width() - 150) / 2 + '" y="' + that.$('svg').height() / 2 + '" fill="black">No lineage data found</text>');
+                    obj['id'] = relationObj.guid;
+                    if (relationObj.status) {
+                        obj['status'] = relationObj.status;
+                    }
+                    if (that.typeMap && that.typeMap[relationObj.typeName]) {
+                        obj['isProcess'] = _.contains(that.typeMap[relationObj.typeName], "Process") ? true : false;
+                    } else {
+                        that.typeMap[relationObj.typeName] = { fetch: true }
+                        fetchEntity(relationObj.typeName);
                     }
+                    return obj;
                 }
-            },
-            createGraph: function(edgesAndvertices, startingPoint) {
-                var that = this,
-                    lastVal = "";
-                _.each(startingPoint, function(val, key, obj) {
-                    _.each(edgesAndvertices.edges[val], function(val1) {
-                        if (val && val1) {
-                            that.g.setEdge(val, val1, { 'arrowhead': "arrowPoint", lineInterpolate: 'basis' });
-                        }
-                        createRemaningEdge(edgesAndvertices.edges, val1);
-                    });
-                });
 
-                function createRemaningEdge(obj, starting) {
-                    if (obj[starting] && obj[starting].length) {
-                        _.each(obj[starting], function(val, key) {
-                            if (starting && val) {
-                                that.g.setEdge(starting, val, { 'arrowhead': "arrowPoint", lineInterpolate: 'basis' });
-                            }
-                            createRemaningEdge(obj, val);
-                        });
+                _.each(relations, function(obj, index) {
+                    if (!that.fromToObj[obj.fromEntityId]) {
+                        that.fromToObj[obj.fromEntityId] = makeNodeObj(guidEntityMap[obj.fromEntityId]);
+                        that.g.setNode(obj.fromEntityId, that.fromToObj[obj.fromEntityId]);
+                    }
+                    if (!that.fromToObj[obj.toEntityId]) {
+                        that.fromToObj[obj.toEntityId] = makeNodeObj(guidEntityMap[obj.toEntityId]);
+                        that.g.setNode(obj.toEntityId, that.fromToObj[obj.toEntityId]);
                     }
+                    that.g.setEdge(obj.fromEntityId, obj.toEntityId, { 'arrowhead': "arrowPoint", lineInterpolate: 'basis' });
+                });
+                if (this.asyncFetchCounter == 0) {
+                    this.createGraph();
                 }
+            },
+            createGraph: function() {
+                var that = this
 
                 this.g.nodes().forEach(function(v) {
                     var node = that.g.node(v);
@@ -290,169 +185,164 @@ define(['require',
                         node.rx = node.ry = 5;
                     }
                 });
-                if (this.outputState) {
-                    // Create the renderer
-                    var render = new dagreD3.render();
-                    // Add our custom arrow (a hollow-point)
-                    render.arrows().arrowPoint = function normal(parent, id, edge, type) {
-                        var marker = parent.append("marker")
-                            .attr("id", id)
-                            .attr("viewBox", "0 0 10 10")
-                            .attr("refX", 9)
-                            .attr("refY", 5)
-                            .attr("markerUnits", "strokeWidth")
-                            .attr("markerWidth", 10)
-                            .attr("markerHeight", 8)
-                            .attr("orient", "auto");
+                // Create the renderer
+                var render = new dagreD3.render();
+                // Add our custom arrow (a hollow-point)
+                render.arrows().arrowPoint = function normal(parent, id, edge, type) {
+                    var marker = parent.append("marker")
+                        .attr("id", id)
+                        .attr("viewBox", "0 0 10 10")
+                        .attr("refX", 9)
+                        .attr("refY", 5)
+                        .attr("markerUnits", "strokeWidth")
+                        .attr("markerWidth", 10)
+                        .attr("markerHeight", 8)
+                        .attr("orient", "auto");
 
-                        var path = marker.append("path")
-                            .attr("d", "M 0 0 L 10 5 L 0 10 z")
-                            .style("stroke-width", 1)
-                            .style("stroke-dasharray", "1,0")
-                            .style("fill", "#cccccc")
-                            .style("stroke", "#cccccc");
-                        dagreD3.util.applyStyle(path, edge[type + "Style"]);
-                    };
-                    render.shapes().img = function circle(parent, bbox, node) {
-                        //var r = Math.max(bbox.width, bbox.height) / 2,
-                        var shapeSvg = parent.insert("image")
-                            .attr("class", "nodeImage")
-                            .attr("xlink:href", function(d) {
-                                if (node) {
-                                    if (node.typeName) {
-                                        if (Globals.entityStateReadOnly[node.state]) {
-                                            return '../img/icon-table-delete.png';
-                                        } else if (node.id == that.guid) {
-                                            return '../img/icon-table-active.png';
-                                        } else {
-                                            return '../img/icon-table.png';
-                                        }
+                    var path = marker.append("path")
+                        .attr("d", "M 0 0 L 10 5 L 0 10 z")
+                        .style("stroke-width", 1)
+                        .style("stroke-dasharray", "1,0")
+                        .style("fill", "#cccccc")
+                        .style("stroke", "#cccccc");
+                    dagreD3.util.applyStyle(path, edge[type + "Style"]);
+                };
+                render.shapes().img = function circle(parent, bbox, node) {
+                    //var r = Math.max(bbox.width, bbox.height) / 2,
+                    var shapeSvg = parent.insert("image")
+                        .attr("class", "nodeImage")
+                        .attr("xlink:href", function(d) {
+                            if (node) {
+                                if (node.isProcess) {
+                                    if (Enums.entityStateReadOnly[node.status]) {
+                                        return '../img/icon-gear-delete.png';
+                                    } else if (node.id == that.guid) {
+                                        return '../img/icon-gear-active.png';
                                     } else {
-                                        if (Globals.entityStateReadOnly[node.state]) {
-                                            return '../img/icon-gear-delete.png';
-                                        } else if (node.id == that.guid) {
-                                            return '../img/icon-gear-active.png';
-                                        } else {
-                                            return '../img/icon-gear.png';
-                                        }
+                                        return '../img/icon-gear.png';
+                                    }
+                                } else {
+                                    if (Enums.entityStateReadOnly[node.status]) {
+                                        return '../img/icon-table-delete.png';
+                                    } else if (node.id == that.guid) {
+                                        return '../img/icon-table-active.png';
+                                    } else {
+                                        return '../img/icon-table.png';
                                     }
                                 }
-                            }).attr("x", "-12px")
-                            .attr("y", "-12px")
-                            .attr("width", "24px")
-                            .attr("height", "24px");
-                        /*shapeSvg = parent.insert("circle", ":first-child")
-                            .attr("x", 35)
-                            .attr("y", 35)
-                            .attr("r", 20);*/
-                        node.intersect = function(point) {
-                            //return dagreD3.intersect.circle(node, points, point);
-                            return dagreD3.intersect.circle(node, 13, point);
-                        };
-                        return shapeSvg;
+                            }
+                        }).attr("x", "-12px")
+                        .attr("y", "-12px")
+                        .attr("width", "24px")
+                        .attr("height", "24px");
+                    node.intersect = function(point) {
+                        //return dagreD3.intersect.circle(node, points, point);
+                        return dagreD3.intersect.circle(node, 13, point);
                     };
-                    // Set up an SVG group so that we can translate the final graph.
-                    var svg = d3.select(this.$("svg")[0]),
-                        svgGroup = svg.append("g");
-                    var zoom = d3.behavior.zoom()
-                        .scaleExtent([0.5, 6])
-                        .on("zoom", zoomed);
+                    return shapeSvg;
+                };
+                // Set up an SVG group so that we can translate the final graph.
+                var svg = d3.select(this.$("svg")[0]),
+                    svgGroup = svg.append("g");
+                var zoom = d3.behavior.zoom()
+                    .scaleExtent([0.5, 6])
+                    .on("zoom", zoomed);
 
-                    function zoomed() {
-                        svgGroup.attr("transform",
-                            "translate(" + zoom.translate() + ")" +
-                            "scale(" + zoom.scale() + ")"
-                        );
-                    }
+                function zoomed() {
+                    svgGroup.attr("transform",
+                        "translate(" + zoom.translate() + ")" +
+                        "scale(" + zoom.scale() + ")"
+                    );
+                }
 
-                    function interpolateZoom(translate, scale) {
-                        var self = this;
-                        return d3.transition().duration(350).tween("zoom", function() {
-                            var iTranslate = d3.interpolate(zoom.translate(), translate),
-                                iScale = d3.interpolate(zoom.scale(), scale);
-                            return function(t) {
-                                zoom
-                                    .scale(iScale(t))
-                                    .translate(iTranslate(t));
-                                zoomed();
-                            };
-                        });
-                    }
+                function interpolateZoom(translate, scale) {
+                    var self = this;
+                    return d3.transition().duration(350).tween("zoom", function() {
+                        var iTranslate = d3.interpolate(zoom.translate(), translate),
+                            iScale = d3.interpolate(zoom.scale(), scale);
+                        return function(t) {
+                            zoom
+                                .scale(iScale(t))
+                                .translate(iTranslate(t));
+                            zoomed();
+                        };
+                    });
+                }
 
-                    function zoomClick() {
-                        var clicked = d3.event.target,
-                            direction = 1,
-                            factor = 0.2,
-                            target_zoom = 1,
-                            center = [that.g.graph().width / 2, that.g.graph().height / 2],
-                            extent = zoom.scaleExtent(),
-                            translate = zoom.translate(),
-                            translate0 = [],
-                            l = [],
-                            view = { x: translate[0], y: translate[1], k: zoom.scale() };
+                function zoomClick() {
+                    var clicked = d3.event.target,
+                        direction = 1,
+                        factor = 0.2,
+                        target_zoom = 1,
+                        center = [that.g.graph().width / 2, that.g.graph().height / 2],
+                        extent = zoom.scaleExtent(),
+                        translate = zoom.translate(),
+                        translate0 = [],
+                        l = [],
+                        view = { x: translate[0], y: translate[1], k: zoom.scale() };
 
-                        d3.event.preventDefault();
-                        direction = (this.id === 'zoom_in') ? 1 : -1;
-                        target_zoom = zoom.scale() * (1 + factor * direction);
+                    d3.event.preventDefault();
+                    direction = (this.id === 'zoom_in') ? 1 : -1;
+                    target_zoom = zoom.scale() * (1 + factor * direction);
 
-                        if (target_zoom < extent[0] || target_zoom > extent[1]) {
-                            return false;
-                        }
+                    if (target_zoom < extent[0] || target_zoom > extent[1]) {
+                        return false;
+                    }
 
-                        translate0 = [(center[0] - view.x) / view.k, (center[1] - view.y) / view.k];
-                        view.k = target_zoom;
-                        l = [translate0[0] * view.k + view.x, translate0[1] * view.k + view.y];
+                    translate0 = [(center[0] - view.x) / view.k, (center[1] - view.y) / view.k];
+                    view.k = target_zoom;
+                    l = [translate0[0] * view.k + view.x, translate0[1] * view.k + view.y];
 
-                        view.x += center[0] - l[0];
-                        view.y += center[1] - l[1];
+                    view.x += center[0] - l[0];
+                    view.y += center[1] - l[1];
 
-                        interpolateZoom([view.x, view.y], view.k);
-                    }
-                    d3.selectAll('button.zoomButton').on('click', zoomClick);
-                    var tooltip = d3Tip()
-                        .attr('class', 'd3-tip')
-                        .html(function(d) {
-                            var value = that.g.node(d);
-                            var htmlStr = "<h5>Name: <span style='color:#359f89'>" + value.toolTiplabel + "</span></h5> ";
-                            if (value.queryText) {
-                                htmlStr += "<h5>Query: <span style='color:#359f89'>" + value.queryText + "</span></h5> ";
-                            }
-                            return htmlStr;
-                        });
-                    svg.call(zoom)
-                        .call(tooltip);
-                    this.$('.fontLoader').hide();
-                    render(svgGroup, this.g);
-                    svg.on("dblclick.zoom", null)
-                        .on("wheel.zoom", null);
-                    //change text postion 
-                    svgGroup.selectAll("g.nodes g.label")
-                        .attr("transform", "translate(2,-30)");
+                    interpolateZoom([view.x, view.y], view.k);
+                }
+                d3.selectAll('button.zoomButton').on('click', zoomClick);
+                var tooltip = d3Tip()
+                    .attr('class', 'd3-tip')
+                    .html(function(d) {
+                        var value = that.g.node(d);
+                        var htmlStr = "<h5>Name: <span style='color:#359f89'>" + value.toolTiplabel + "</span></h5> ";
+                        if (value.queryText) {
+                            htmlStr += "<h5>Query: <span style='color:#359f89'>" + value.queryText + "</span></h5> ";
+                        }
+                        return htmlStr;
+                    });
+                svg.call(zoom)
+                    .call(tooltip);
+                this.$('.fontLoader').hide();
+                render(svgGroup, this.g);
+                svg.on("dblclick.zoom", null)
+                    .on("wheel.zoom", null);
+                //change text postion 
+                svgGroup.selectAll("g.nodes g.label")
+                    .attr("transform", "translate(2,-30)");
 
-                    svgGroup.selectAll("g.nodes image")
-                        .on('mouseover', function(d) {
-                            tooltip.show(d);
-                        })
-                        .on('dblclick', function(d) {
-                            tooltip.hide(d);
-                            //var urlForTab = window.location.hash.split('/')[1];
+                svgGroup.selectAll("g.nodes image")
+                    .on('mouseover', function(d) {
+                        tooltip.show(d);
+                    })
+                    .on('dblclick', function(d) {
+                        tooltip.hide(d);
+                        //var urlForTab = window.location.hash.split('/')[1];
 
-                            Utils.setUrl({
-                                url: '#!/detailPage/' + d,
-                                mergeBrowserUrl: false,
-                                trigger: true
-                            });
-                        })
-                        .on('mouseout', function(d) {
-                            tooltip.hide(d);
+                        Utils.setUrl({
+                            url: '#!/detailPage/' + d,
+                            mergeBrowserUrl: false,
+                            trigger: true
                         });
-                    // Center the graph
-                    var initialScale = 1.2;
-                    zoom.translate([(this.$('svg').width() - this.g.graph().width * initialScale) / 2, (this.$('svg').height() - this.g.graph().height * initialScale) / 2])
-                        .scale(initialScale)
-                        .event(svg);
-                    //svg.attr('height', this.g.graph().height * initialScale + 40);
-                }
+                    })
+                    .on('mouseout', function(d) {
+                        tooltip.hide(d);
+                    });
+                // Center the graph
+                var initialScale = 1.2;
+                zoom.translate([(this.$('svg').width() - this.g.graph().width * initialScale) / 2, (this.$('svg').height() - this.g.graph().height * initialScale) / 2])
+                    .scale(initialScale)
+                    .event(svg);
+                //svg.attr('height', this.g.graph().height * initialScale + 40);
+
             }
         });
     return LineageLayoutView;

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/efc8d09c/dashboardv2/public/js/views/schema/SchemaLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/schema/SchemaLayoutView.js b/dashboardv2/public/js/views/schema/SchemaLayoutView.js
index 47a8464..21ab40c 100644
--- a/dashboardv2/public/js/views/schema/SchemaLayoutView.js
+++ b/dashboardv2/public/js/views/schema/SchemaLayoutView.js
@@ -23,8 +23,10 @@ define(['require',
     'utils/Utils',
     'utils/CommonViewFunction',
     'utils/Messages',
-    'utils/Globals'
-], function(require, Backbone, SchemaTableLayoutViewTmpl, VSchemaList, Utils, CommonViewFunction, Messages, Globals) {
+    'utils/Globals',
+    'utils/Enums',
+    'utils/UrlLinks'
+], function(require, Backbone, SchemaTableLayoutViewTmpl, VSchemaList, Utils, CommonViewFunction, Messages, Globals, Enums, UrlLinks) {
     'use strict';
 
     var SchemaTableLayoutView = Backbone.Marionette.LayoutView.extend(
@@ -91,7 +93,7 @@ define(['require',
             initialize: function(options) {
                 _.extend(this, _.pick(options, 'globalVent', 'guid', 'vent'));
                 this.schemaCollection = new VSchemaList([], {});
-                this.schemaCollection.url = "/api/atlas/lineage/" + this.guid + "/schema";
+                this.schemaCollection.url = UrlLinks.schemaApiUrl(this.guid);
                 this.commonTableOptions = {
                     collection: this.schemaCollection,
                     includeFilter: false,
@@ -252,7 +254,7 @@ define(['require',
                                 } else {
                                     nameHtml = '<a>' + rawValue + '</a>';
                                 }
-                                if (model.get('$id$') && model.get('$id$').state && Globals.entityStateReadOnly[model.get('$id$').state]) {
+                                if (model.get('$id$') && model.get('$id$').state && Enums.entityStateReadOnly[model.get('$id$').state]) {
                                     nameHtml += '<button type="button" title="Deleted" class="btn btn-atlasAction btn-atlas deleteBtn"><i class="fa fa-trash"></i></button>';
                                     return '<div class="readOnly readOnlyLink">' + nameHtml + '</div>';
                                 } else {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/efc8d09c/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 f2b8a38..d652aa4 100644
--- a/dashboardv2/public/js/views/search/SearchLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchLayoutView.js
@@ -21,7 +21,8 @@ define(['require',
     'hbs!tmpl/search/SearchLayoutView_tmpl',
     'collection/VTagList',
     'utils/Utils',
-], function(require, Backbone, SearchLayoutViewTmpl, VTagList, Utils) {
+    'utils/UrlLinks'
+], function(require, Backbone, SearchLayoutViewTmpl, VTagList, Utils, UrlLinks) {
     'use strict';
 
     var SearchLayoutView = Backbone.Marionette.LayoutView.extend(
@@ -71,6 +72,7 @@ define(['require',
             initialize: function(options) {
                 _.extend(this, _.pick(options, 'globalVent', 'value'));
                 this.typecollection = new VTagList([], {});
+                this.typecollection.url = UrlLinks.typesApiUrl();
                 this.type = "fulltext";
                 var param = Utils.getUrlState.getQueryParams();
                 this.query = {
@@ -104,7 +106,6 @@ define(['require',
                 this.ui.searchBtn.attr("disabled", "true");
             },
             fetchCollection: function(value) {
-                $.extend(this.typecollection.queryParams, { type: 'CLASS' });
                 this.typecollection.fetch({ reset: true });
             },
             onRefreshButton: function() {
@@ -118,10 +119,10 @@ define(['require',
                 this.ui.typeLov.empty();
                 var str = '<option></option>';
                 this.typecollection.fullCollection.comparator = function(model) {
-                    return model.get('tags').toLowerCase();
+                    return model.get('name').toLowerCase();
                 }
                 this.typecollection.fullCollection.sort().each(function(model) {
-                    str += '<option>' + model.get("tags") + '</option>';
+                    str += '<option>' + model.get("name") + '</option>';
                 });
                 that.ui.typeLov.html(str);
             },

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/efc8d09c/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 2eca6a1..0a37834 100644
--- a/dashboardv2/public/js/views/search/SearchResultLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchResultLayoutView.js
@@ -26,8 +26,10 @@ define(['require',
     'collection/VSearchList',
     'models/VCommon',
     'utils/CommonViewFunction',
-    'utils/Messages'
-], function(require, Backbone, SearchResultLayoutViewTmpl, Modal, VEntity, Utils, Globals, VSearchList, VCommon, CommonViewFunction, Messages) {
+    'utils/Messages',
+    'utils/Enums',
+    'utils/UrlLinks'
+], function(require, Backbone, SearchResultLayoutViewTmpl, Modal, VEntity, Utils, Globals, VSearchList, VCommon, CommonViewFunction, Messages, Enums, UrlLinks) {
     'use strict';
 
     var SearchResultLayoutView = Backbone.Marionette.LayoutView.extend(
@@ -70,7 +72,7 @@ define(['require',
                             var url = scope.data('href').split(".").join("/terms/");
                             Globals.saveApplicationState.tabState.stateChanged = false;
                             Utils.setUrl({
-                                url: '#!/taxonomy/detailCatalog/api/atlas/v1/taxonomies/' + url,
+                                url: '#!/taxonomy/detailCatalog' + UrlLinks.taxonomiesApiUrl() + '/' + url,
                                 mergeBrowserUrl: false,
                                 trigger: true
                             });
@@ -214,12 +216,12 @@ define(['require',
                 $.extend(this.searchCollection.queryParams, { limit: this.limit });
                 if (value) {
                     if (value.searchType) {
-                        this.searchCollection.url = "/api/atlas/discovery/search/" + value.searchType;
+                        this.searchCollection.url = UrlLinks.searchApiUrl(value.searchType);
                         $.extend(this.searchCollection.queryParams, { limit: this.limit });
                         this.offset = 0;
                     }
                     if (Utils.getUrlState.isTagTab()) {
-                        this.searchCollection.url = "/api/atlas/discovery/search/dsl";
+                        this.searchCollection.url = UrlLinks.searchApiUrl(Enums.searchUrlType.DSL);
                     }
                     _.extend(this.searchCollection.queryParams, { 'query': value.query.trim() });
                 }
@@ -347,19 +349,17 @@ define(['require',
                                 ++that.asyncFetchCounter;
                                 model.getEntity(guid, {
                                     success: function(data) {
-                                        if (data.definition) {
-                                            if (data.definition.id && data.definition.values) {
+                                        if (data.attributes) {
+                                            if (data.guid && data.attributes) {
                                                 var id = "";
-                                                if (_.isObject(data.definition.id) && data.definition.id.id) {
-                                                    id = data.definition.id.id;
-                                                } else {
-                                                    id = data.definition.id;
+                                                id = data.guid;
+                                                if (that.searchCollection.get(id)) {
+                                                    that.searchCollection.get(id).set(data.attributes);
+                                                    that.searchCollection.get(id).set({
+                                                        '$id$': data.guid,
+                                                        '$traits$': data.classifications
+                                                    });
                                                 }
-                                                that.searchCollection.get(id).set(data.definition.values);
-                                                that.searchCollection.get(id).set({
-                                                    '$id$': data.definition.id,
-                                                    '$traits$': data.definition.traits
-                                                });
                                             }
                                         }
                                     },
@@ -441,12 +441,12 @@ define(['require',
                                         return "";
                                     }
                                 }
-                                if (model.get('$id$') && model.get('$id$').id) {
-                                    nameHtml = '<a href="#!/detailPage/' + model.get('$id$').id + '">' + rawValue + '</a>';
+                                if (model.get('$id$')) {
+                                    nameHtml = '<a href="#!/detailPage/' + (model.get('$id$').id || model.get('$id$')) + '">' + rawValue + '</a>';
                                 } else {
                                     nameHtml = '<a>' + rawValue + '</a>';
                                 }
-                                if (model.get('$id$') && model.get('$id$').state && Globals.entityStateReadOnly[model.get('$id$').state]) {
+                                if (model.get('$id$') && model.get('$id$').state && Enums.entityStateReadOnly[model.get('$id$').state]) {
                                     nameHtml += '<button type="button" title="Deleted" class="btn btn-atlasAction btn-atlas deleteBtn"><i class="fa fa-trash"></i></button>';
                                     return '<div class="readOnly readOnlyLink">' + nameHtml + '</div>';
                                 } else {
@@ -476,12 +476,12 @@ define(['require',
                                         return "";
                                     }
                                 }
-                                if (model.get('$id$') && model.get('$id$').id) {
-                                    nameHtml = '<a href="#!/detailPage/' + model.get('$id$').id + '">' + rawValue + '</a>';
+                                if (model.get('$id$')) {
+                                    nameHtml = '<a href="#!/detailPage/' + (model.get('$id$').id || model.get('$id$')) + '">' + rawValue + '</a>';
                                 } else {
                                     nameHtml = '<a>' + rawValue + '</a>';
                                 }
-                                if (model.get('$id$') && model.get('$id$').state && Globals.entityStateReadOnly[model.get('$id$').state]) {
+                                if (model.get('$id$') && model.get('$id$').state && Enums.entityStateReadOnly[model.get('$id$').state]) {
                                     nameHtml += '<button type="button" title="Deleted" class="btn btn-atlasAction btn-atlas deleteBtn"><i class="fa fa-trash"></i></button>';
                                     return '<div class="readOnly readOnlyLink">' + nameHtml + '</div>';
                                 } else {
@@ -513,7 +513,7 @@ define(['require',
                     className: 'searchTag',
                     formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
                         fromRaw: function(rawValue, model) {
-                            if (model.get('$id$') && model.get('$id$').state && Globals.entityStateReadOnly[model.get('$id$').state]) {
+                            if (model.get('$id$') && model.get('$id$').state && Enums.entityStateReadOnly[model.get('$id$').state]) {
                                 return '<div class="readOnly">' + CommonViewFunction.tagForTable(model); + '</div>';
                             } else {
                                 return CommonViewFunction.tagForTable(model);
@@ -536,7 +536,7 @@ define(['require',
                                 if (returnObject.object) {
                                     that.bradCrumbList.push(returnObject.object);
                                 }
-                                if (model.get('$id$') && model.get('$id$').state && Globals.entityStateReadOnly[model.get('$id$').state]) {
+                                if (model.get('$id$') && model.get('$id$').state && Enums.entityStateReadOnly[model.get('$id$').state]) {
                                     return '<div class="readOnly">' + returnObject.html + '</div>';
                                 } else {
                                     return returnObject.html;

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/efc8d09c/dashboardv2/public/js/views/tag/CreateTagLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/tag/CreateTagLayoutView.js b/dashboardv2/public/js/views/tag/CreateTagLayoutView.js
index 8ff076a..fee04b5 100644
--- a/dashboardv2/public/js/views/tag/CreateTagLayoutView.js
+++ b/dashboardv2/public/js/views/tag/CreateTagLayoutView.js
@@ -1,4 +1,3 @@
-
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -58,9 +57,9 @@ define(['require',
              * @constructs
              */
             initialize: function(options) {
-                _.extend(this, _.pick(options, 'tagCollection', 'tag', 'termCollection', 'descriptionData'));
-                if (this.tagCollection && this.tagCollection.length > 0 && this.tagCollection.first().get('traitTypes')) {
-                    this.description = this.tagCollection.first().get('traitTypes')[0].typeDescription;
+                _.extend(this, _.pick(options, 'tagCollection', 'model', 'tag', 'termCollection', 'descriptionData'));
+                if (this.model) {
+                    this.description = this.model.get('description');
                 } else if (this.termCollection) {
                     this.description = this.descriptionData;
                 } else {
@@ -80,7 +79,7 @@ define(['require',
                     that = this;
                 this.ui.parentTag.empty();
                 this.tagCollection.fullCollection.each(function(val) {
-                    str += '<option>' + val.get("tags") + '</option>';
+                    str += '<option>' + val.get("name") + '</option>';
                 });
                 that.ui.parentTag.html(str);
                 console.log(platform);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/efc8d09c/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js b/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
index e115f83..4dc8c38 100644
--- a/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
+++ b/dashboardv2/public/js/views/tag/TagAttributeDetailLayoutView.js
@@ -21,10 +21,11 @@ define(['require',
     'hbs!tmpl/tag/TagAttributeDetailLayoutView_tmpl',
     'utils/Utils',
     'views/tag/AddTagAttributeView',
-    'collection/VCommonList',
+    'collection/VTagList',
     'models/VTag',
-    'utils/Messages'
-], function(require, Backbone, TagAttributeDetailLayoutViewTmpl, Utils, AddTagAttributeView, VCommonList, VTag, Messages) {
+    'utils/Messages',
+    'utils/UrlLinks'
+], function(require, Backbone, TagAttributeDetailLayoutViewTmpl, Utils, AddTagAttributeView, VTagList, VTag, Messages, UrlLinks) {
     'use strict';
 
     var TagAttributeDetailLayoutView = Backbone.Marionette.LayoutView.extend(
@@ -63,32 +64,12 @@ define(['require',
              * @constructs
              */
             initialize: function(options) {
-                _.extend(this, _.pick(options, 'globalVent', 'tag', 'vent'));
-                this.tagCollection = new VCommonList();
-                this.tagCollection.url = "/api/atlas/types/" + this.tag;
-                this.tagCollection.modelAttrName = "definition";
-                this.tagCollection.fetch({ reset: true });
-                this.bindEvents();
+                _.extend(this, _.pick(options, 'globalVent', 'tag', 'collection'));
             },
             bindEvents: function() {
-                this.listenTo(this.tagCollection, 'reset', function() {
-                    var that = this,
-                        attributeData = "";
-                    _.each(this.tagCollection.models, function(attr) {
-                        var traitTypes = attr.get("traitTypes");
-                        if (traitTypes[0].typeDescription != null) {
-                            var descriptionValue = traitTypes[0].typeDescription;
-                            that.ui.description.html(descriptionValue);
-                        }
-                        _.each(traitTypes[0].attributeDefinitions, function(value, key) {
-                            attributeData += '<span class="inputAttribute">' + value.name + '</span>';
-                        });
-                    });
-                    if (attributeData.length) {
-                        that.ui.addTagtext.hide();
-                        that.ui.addTagPlus.show();
-                    }
-                    that.ui.showAttribute.html(attributeData);
+                this.listenTo(this.collection, 'reset', function() {
+                    this.model = this.collection.findWhere({ name: this.tag });
+                    this.renderTagDetail();
                 }, this);
                 this.listenTo(this.tagCollection, 'error', function(error, response) {
                     if (response.responseJSON && response.responseJSON.error) {
@@ -100,24 +81,47 @@ define(['require',
                 }, this);
             },
             onRender: function() {
-                this.ui.title.html('<span>' + this.tag + '</span>');
+                if (this.collection.models.length && !this.model) {
+                    this.model = this.collection.findWhere({ name: this.tag });
+                    this.renderTagDetail();
+                }
+                this.bindEvents();
                 this.ui.saveButton.attr("disabled", "true");
                 this.ui.publishButton.prop('disabled', true);
             },
+            renderTagDetail: function() {
+                var attributeData = "",
+                    attributeDefs = this.model.get("attributeDefs");
+                if (this.model.get("name")) {
+                    this.ui.title.html('<span>' + this.model.get("name") + '</span>');
+                }
+                if (this.model.get("description")) {
+                    this.ui.description.html(this.model.get("description"));
+                }
+                if (this.model.get("attributeDefs")) {
+                    if (!_.isArray(attributeDefs)) {
+                        attributeDefs = [attributeDefs];
+                    }
+                    _.each(attributeDefs, function(value, key) {
+                        attributeData += '<span class="inputAttribute">' + value.name + '</span>';
+                    });
+                    this.ui.showAttribute.html(attributeData);
+                }
+
+            },
             onSaveButton: function(saveObject, message) {
-                var that = this,
-                    tagModel = new VTag();
-                tagModel.set(saveObject).save(null, {
-                    type: "PUT",
+                var that = this;
+                this.model.saveTagAttribute(this.model.get('name'), {
+                    data: JSON.stringify(saveObject),
                     success: function(model, response) {
-                        that.tagCollection.fetch({ reset: true });
+                        that.model.set(model);
+                        that.renderTagDetail();
                         Utils.notifySuccess({
                             content: message
                         });
                     },
                     error: function(model, response) {
                         if (response.responseJSON && response.responseJSON.error) {
-                            that.tagCollection.fetch({ reset: true });
                             Utils.notifyError({
                                 content: response.responseJSON.error
                             });
@@ -141,16 +145,20 @@ define(['require',
                             }).open();
                         modal.on('ok', function() {
                             var attributeName = $(view.el).find("input").val();
-                            that.tagCollection.first().get('traitTypes')[0].attributeDefinitions.push({
+                            var attributes = _.clone(that.model.get('attributeDefs'));
+                            if (!_.isArray(attributes)) {
+                                attributes = [attributes];
+                            }
+                            attributes.push({
                                 "name": attributeName,
-                                "dataTypeName": "string",
-                                "multiplicity": "optional",
-                                "isComposite": false,
-                                "isUniquvar e": false,
-                                "isIndexable": true,
-                                "reverseAttributeName": null
+                                "typeName": "string",
+                                "cardinality": "SINGLE",
+                                "isUnique": false,
+                                "indexable": true,
+                                "isOptional":true
                             });
-                            that.onSaveButton(that.tagCollection.first().toJSON(), Messages.addAttributeSuccessMessage);
+                            var saveData = _.extend(that.model.toJSON(), { 'attributeDefs': attributes });
+                            that.onSaveButton(saveData, Messages.addAttributeSuccessMessage);
                         });
                         modal.on('closeModal', function() {
                             modal.trigger('cancel');
@@ -163,15 +171,15 @@ define(['require',
                 this.ui.editBox.hide();
             },
             textAreaChangeEvent: function(view, modal) {
-                if (view.tagCollection.first().get('traitTypes')[0].typeDescription == view.ui.description.val()) {
+                if (this.model.get('description') === view.ui.description.val()) {
                     modal.$el.find('button.ok').prop('disabled', true);
                 } else {
                     modal.$el.find('button.ok').prop('disabled', false);
                 }
             },
             onPublishClick: function(view) {
-                view.tagCollection.first().get('traitTypes')[0].typeDescription = view.ui.description.val();
-                this.onSaveButton(this.tagCollection.first().toJSON(), Messages.updateTagDescriptionMessage);
+                var saveObj = _.extend(this.model.toJSON(), { 'description': view.ui.description.val() });
+                this.onSaveButton(saveObj, Messages.updateTagDescriptionMessage);
                 this.ui.description.show();
             },
             onEditButton: function(e) {
@@ -181,7 +189,7 @@ define(['require',
                     'views/tag/CreateTagLayoutView',
                     'modules/Modal'
                 ], function(CreateTagLayoutView, Modal) {
-                    var view = new CreateTagLayoutView({ 'tagCollection': that.tagCollection, 'tag': that.tag });
+                    var view = new CreateTagLayoutView({ 'tagCollection': that.collection, 'model': that.model, 'tag': that.tag });
                     var modal = new Modal({
                         title: 'Edit Tag',
                         content: view,

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/efc8d09c/dashboardv2/public/js/views/tag/TagDetailLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/tag/TagDetailLayoutView.js b/dashboardv2/public/js/views/tag/TagDetailLayoutView.js
index bcc9c78..e9e1ab4 100644
--- a/dashboardv2/public/js/views/tag/TagDetailLayoutView.js
+++ b/dashboardv2/public/js/views/tag/TagDetailLayoutView.js
@@ -44,7 +44,7 @@ define(['require',
              * @constructs
              */
             initialize: function(options) {
-                _.extend(this, _.pick(options, 'globalVent', 'guid', 'tag'));
+                _.extend(this, _.pick(options, 'globalVent', 'tag', 'collection'));
             },
             bindEvents: function() {},
             onRender: function() {
@@ -68,7 +68,8 @@ define(['require',
                 var that = this;
                 require(['views/tag/TagAttributeDetailLayoutView'], function(TagAttributeDetailLayoutView) {
                     that.RTagAttributeDetailLayoutView.show(new TagAttributeDetailLayoutView({
-                        tag: that.tag
+                        tag: that.tag,
+                        collection: that.collection
                     }));
                 });
             },

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/efc8d09c/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js b/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js
index 283b889..06cc8b1 100644
--- a/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js
+++ b/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js
@@ -61,9 +61,9 @@ define(['require',
              */
             initialize: function(options) {
                 _.extend(this, _.pick(options, 'globalVent', 'collection', 'guid', 'term', 'assetName'));
-                this.collectionObject = this.collection.toJSON();
+                this.collectionObject = this.collection.first().toJSON();
                 this.tagTermCollection = new VTagList();
-                var tagorterm = _.toArray(this.collectionObject[0].traits),
+                var tagorterm = _.toArray(this.collectionObject.classifications),
                     tagTermList = [],
                     that = this;
                 _.each(tagorterm, function(object) {
@@ -130,7 +130,7 @@ define(['require',
                             sortable: false,
                             formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
                                 fromRaw: function(rawValue, model) {
-                                    var values = model.get('values'),
+                                    var values = model.get('attributes'),
                                         tagValue = 'NA';
                                     if (!_.isEmpty(values)) {
                                         var stringArr = [];

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/efc8d09c/dashboardv2/public/js/views/tag/TagLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/tag/TagLayoutView.js b/dashboardv2/public/js/views/tag/TagLayoutView.js
index b22c0ec..1994951 100644
--- a/dashboardv2/public/js/views/tag/TagLayoutView.js
+++ b/dashboardv2/public/js/views/tag/TagLayoutView.js
@@ -23,8 +23,9 @@ define(['require',
     'collection/VEntityList',
     'utils/Utils',
     'utils/Messages',
-    'utils/Globals'
-], function(require, Backbone, TagLayoutViewTmpl, VTagList, VEntityList, Utils, Messages, Globals) {
+    'utils/Globals',
+    'utils/UrlLinks'
+], function(require, Backbone, TagLayoutViewTmpl, VTagList, VEntityList, Utils, Messages, Globals, UrlLinks) {
     'use strict';
 
     var TagLayoutView = Backbone.Marionette.LayoutView.extend(
@@ -45,7 +46,6 @@ define(['require',
                 offLineSearchTag: "[data-id='offlineSearchTag']",
                 deleteTerm: "[data-id='deleteTerm']",
                 refreshTag: '[data-id="refreshTag"]'
-
             },
             /** ui events hash */
             events: function() {
@@ -62,20 +62,12 @@ define(['require',
              * @constructs
              */
             initialize: function(options) {
-                _.extend(this, _.pick(options, 'globalVent', 'tag'));
-                this.tagCollection = new VTagList();
-                this.collection = new Backbone.Collection();
-                this.json = {
-                    "enumTypes": [],
-                    "traitTypes": [],
-                    "structTypes": [],
-                    "classTypes": []
-                };
+                _.extend(this, _.pick(options, 'globalVent', 'tag', 'collection'));
             },
             bindEvents: function() {
                 var that = this;
-                this.listenTo(this.tagCollection, "reset", function() {
-                    this.tagsAndTypeGenerator('tagCollection');
+                this.listenTo(this.collection, "reset", function() {
+                    this.tagsAndTypeGenerator('collection');
                 }, this);
                 this.ui.tagsParent.on('click', 'li.parent-node a', function() {
                     that.setUrl(this.getAttribute("href"));
@@ -98,8 +90,7 @@ define(['require',
                 });
             },
             fetchCollections: function() {
-                $.extend(this.tagCollection.queryParams, { type: 'TRAIT', notsupertype: 'TaxonomyTerm' });
-                this.tagCollection.fetch({ reset: true });
+                this.collection.fetch({ reset: true });
                 this.ui.offLineSearchTag.val("");
             },
             manualRender: function(tagName) {
@@ -152,19 +143,19 @@ define(['require',
             tagsAndTypeGenerator: function(collection, searchString) {
                 var that = this,
                     str = '';
-                that.tagCollection.fullCollection.comparator = function(model) {
-                    return model.get('tags').toLowerCase();
+                that.collection.fullCollection.comparator = function(model) {
+                    return model.get('name').toLowerCase();
                 };
-                that.tagCollection.fullCollection.sort().each(function(model) {
+                that.collection.fullCollection.sort().each(function(model) {
                     if (searchString) {
-                        if (model.get('tags').search(new RegExp(searchString, "i")) != -1) {
+                        if (model.get('name').search(new RegExp(searchString, "i")) != -1) {
                             // data-name="<space>'<tagName>'"  Space is required for DSL search Input 
-                            str += '<li class="parent-node" data-id="tags"><div class="tools"><i class="fa fa-ellipsis-h tagPopover"></i></div><a href="#!/tag/tagAttribute/' + model.get('tags') + '"  data-name=" `' + model.get('tags') + '`" >' + model.get('tags') + '</a></li>';
+                            str += '<li class="parent-node" data-id="tags"><div class="tools"><i class="fa fa-ellipsis-h tagPopover"></i></div><a href="#!/tag/tagAttribute/' + model.get('name') + '"  data-name="`' + model.get('name') + '`" >' + model.get('name') + '</a></li>';
                         } else {
                             return;
                         }
                     } else {
-                        str += '<li class="parent-node" data-id="tags"><div class="tools"><i class="fa fa-ellipsis-h tagPopover"></i></div><a href="#!/tag/tagAttribute/' + model.get('tags') + '"  data-name=" `' + model.get('tags') + '`">' + model.get('tags') + '</a></li>';
+                        str += '<li class="parent-node" data-id="tags"><div class="tools"><i class="fa fa-ellipsis-h tagPopover"></i></div><a href="#!/tag/tagAttribute/' + model.get('name') + '"  data-name="`' + model.get('name') + '`">' + model.get('name') + '</a></li>';
                     }
                 });
                 this.ui.tagsParent.empty().html(str);
@@ -175,7 +166,6 @@ define(['require',
                 }
 
             },
-
             onClickCreateTag: function(e) {
                 var that = this;
                 $(e.currentTarget).blur();
@@ -183,7 +173,7 @@ define(['require',
                     'views/tag/CreateTagLayoutView',
                     'modules/Modal'
                 ], function(CreateTagLayoutView, Modal) {
-                    var view = new CreateTagLayoutView({ 'tagCollection': that.tagCollection });
+                    var view = new CreateTagLayoutView({ 'tagCollection': that.collection });
                     var modal = new Modal({
                         title: 'Create a new tag',
                         content: view,
@@ -223,22 +213,23 @@ define(['require',
                 if (ref.ui.parentTag.val() && ref.ui.parentTag.val()) {
                     superTypes = ref.ui.parentTag.val();
                 }
-                this.json.traitTypes[0] = {
-                    attributeDefinitions: this.collection.toJSON(),
-                    typeName: this.name,
-                    typeDescription: this.description,
-                    superTypes: superTypes,
-                    hierarchicalMetaTypeName: "org.apache.atlas.typesystem.types.TraitType"
+                this.json = {
+                    'name': this.name,
+                    'description': this.description,
+                    "typeVersion": "2",
+                    "version": "2",
+                    'superTypes': superTypes.length ? superTypes : [],
                 };
-                new this.tagCollection.model().set(this.json).save(null, {
+                new this.collection.model().set(this.json).save(null, {
                     success: function(model, response) {
                         that.createTag = true;
                         that.fetchCollections();
+                        that.collection.add(model)
                         that.setUrl('#!/tag/tagAttribute/' + ref.ui.tagName.val(), true);
                         Utils.notifySuccess({
                             content: "Tag " + that.name + Messages.addSuccessMessage
                         });
-                        that.collection.reset([]);
+
                     },
                     error: function(model, response) {
                         if (response.responseJSON && response.responseJSON.error) {
@@ -270,7 +261,7 @@ define(['require',
             },
             offlineSearchTag: function(e) {
                 var type = $(e.currentTarget).data('type');
-                this.tagsAndTypeGenerator('tagCollection', $(e.currentTarget).val());
+                this.tagsAndTypeGenerator('collection', $(e.currentTarget).val());
             },
             createTagAction: function() {
                 var that = this;

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/efc8d09c/dashboardv2/public/js/views/tag/addTagModalView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/tag/addTagModalView.js b/dashboardv2/public/js/views/tag/addTagModalView.js
index 972997c..fdaea5b 100644
--- a/dashboardv2/public/js/views/tag/addTagModalView.js
+++ b/dashboardv2/public/js/views/tag/addTagModalView.js
@@ -22,8 +22,9 @@ define(['require',
     'collection/VCommonList',
     'modules/Modal',
     'models/VEntity',
-    'utils/Utils'
-], function(require, AddTagModalViewTmpl, VTagList, VCommonList, Modal, VEntity, Utils) {
+    'utils/Utils',
+    'utils/UrlLinks'
+], function(require, AddTagModalViewTmpl, VTagList, VCommonList, Modal, VEntity, Utils, UrlLinks) {
     'use strict';
 
     var AddTagModel = Marionette.LayoutView.extend({
@@ -47,7 +48,7 @@ define(['require',
             var that = this;
             _.extend(this, _.pick(options, 'vent', 'modalCollection', 'guid', 'callback', 'multiple', 'showLoader'));
             this.collection = new VTagList();
-            this.commonCollection = new VCommonList();
+            this.commonCollection = new VTagList();
             this.asyncAttrFetchCounter = 0;
             this.modal = new Modal({
                 title: 'Add Tag',
@@ -74,7 +75,7 @@ define(['require',
                         var obj = {
                             tagName: tagName,
                             tagAttributes: tagAttributes,
-                            guid: that.multiple[i].id.id
+                            guid: (_.isObject(that.multiple[i].id) ? that.multiple[i].id.id : that.multiple[i].id)
                         }
                         that.saveTagData(obj);
                     }
@@ -112,12 +113,12 @@ define(['require',
         },
         tagsCollection: function() {
             this.collection.fullCollection.comparator = function(model) {
-                return model.get('tags').toLowerCase();
+                return model.get('name').toLowerCase();
             }
 
             var str = '<option selected="selected" disabled="disabled">-- Select a tag from the dropdown list --</option>';
             this.collection.fullCollection.sort().each(function(obj, key) {
-                str += '<option>' + obj.get('tags') + '</option>';
+                str += '<option>' + obj.get('name') + '</option>';
             });
             this.ui.addTagOptions.html(str);
             this.ui.addTagOptions.select2({
@@ -134,8 +135,7 @@ define(['require',
             this.fetchTagSubData(tagname);
         },
         fetchTagSubData: function(tagname) {
-            this.commonCollection.url = "/api/atlas/types/" + tagname;
-            this.commonCollection.modelAttrName = 'definition';
+            this.commonCollection.url = UrlLinks.typesClassicationApiUrl(tagname);
             ++this.asyncAttrFetchCounter
             this.commonCollection.fetch({ reset: true });
         },
@@ -153,18 +153,28 @@ define(['require',
             this.$('.attrLoader').show();
         },
         subAttributeData: function() {
-            if (this.commonCollection.models[0] && this.commonCollection.models[0].attributes && this.commonCollection.models[0].attributes.traitTypes[0].attributeDefinitions) {
-                for (var i = 0; i < this.commonCollection.models[0].attributes.traitTypes[0].attributeDefinitions.length; i++) {
-                    var attribute = this.commonCollection.models[0].attributes.traitTypes[0].attributeDefinitions;
-                    var strAttribute = '<div class="form-group"><label>' + attribute[i].name + '</label>' +
-                        '<input type="text" class="form-control attributeInputVal attrName" data-key="' + attribute[i].name + '" ></input></div>';
-                    this.ui.tagAttribute.append(strAttribute);
+            var that = this;
+            if (this.commonCollection.models[0]) {
+                if (this.commonCollection.models[0].get('attributeDefs')) {
+                    _.each(this.commonCollection.models[0].get('attributeDefs'), function(obj) {
+                        that.ui.tagAttribute.append('<div class="form-group"><label>' + obj.name + '</label>' +
+                            '<input type="text" class="form-control attributeInputVal attrName" data-key="' + obj.name + '" ></input></div>');
+                    });
                 }
-                if (this.commonCollection.models[0].attributes.traitTypes[0].superTypes.length > 0) {
-                    for (var j = 0; j < this.commonCollection.models[0].attributes.traitTypes[0].superTypes.length; j++) {
-                        var superTypeAttr = this.commonCollection.models[0].attributes.traitTypes[0].superTypes[j];
-                        this.fetchTagSubData(superTypeAttr);
+
+                if (this.commonCollection.models[0].get('superTypes')) {
+                    var superTypes = this.commonCollection.models[0].get('superTypes');
+                    if (!_.isArray(superTypes)) {
+                        superTypes = [superTypes];
                     }
+                    if (superTypes.length) {
+                        _.each(superTypes, function(name) {
+                            that.fetchTagSubData(name);
+                        });
+                    } else {
+                        this.showAttributeBox();
+                    }
+
                 } else {
                     this.showAttributeBox();
                 }
@@ -178,11 +188,10 @@ define(['require',
             this.entityModel = new VEntity();
             var tagName = options.tagName,
                 tagAttributes = options.tagAttributes,
-                json = {
-                    "jsonClass": "org.apache.atlas.typesystem.json.InstanceSerialization$_Struct",
+                json = [{
                     "typeName": tagName,
-                    "values": tagAttributes
-                };
+                    "attributes": tagAttributes
+                }];
             this.entityModel.saveEntity(options.guid, {
                 data: JSON.stringify(json),
                 success: function(data) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/efc8d09c/release-log.txt
----------------------------------------------------------------------
diff --git a/release-log.txt b/release-log.txt
index 6f46fa5..6873101 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -9,6 +9,7 @@ ATLAS-1060 Add composite indexes for exact match performance improvements for al
 ATLAS-1127 Modify creation and modification timestamps to Date instead of Long(sumasai)
 
 ALL CHANGES:
+ATLAS-1287 Subtasks: ATLAS-1288/ATLAS-1289 Integrated V2 API for Lineage,Entity Details,Tag assign to entity,Tags listing,tag create (kevalbhatt)
 ATLAS-1303 Update hashCode and equals method to use standard JDK libraries (apoorvnaik via svimal2106)
 ATLAS-1364 HiveHook : Fix Auth issue with doAs (sumasai)
 ATLAS-1340 Credential Provider utility does not work with fully qualified local/HDFS jceks path (vrathor via svimal2106)


Mime
View raw message