Repository: atlas Updated Branches: refs/heads/master 7b14cfac5 -> 45bf48e6e
ATLAS-2594: UI, Tag propagation : Add dialog box for blocked Propagated classifications list on UI Signed-off-by: Sarath Subramanian <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/atlas/repo Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/45bf48e6 Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/45bf48e6 Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/45bf48e6 Branch: refs/heads/master Commit: 45bf48e6e549c6f8a377512aa32607021cf927e0 Parents: 7b14cfa Author: pratik24mac <[email protected]> Authored: Mon Apr 23 10:34:51 2018 -0700 Committer: Sarath Subramanian <[email protected]> Committed: Mon Apr 23 10:34:51 2018 -0700 ---------------------------------------------------------------------- dashboardv2/public/css/scss/override.scss | 3 + dashboardv2/public/css/scss/theme.scss | 3 + .../PropagationPropertyModalView_tmpl.html | 78 ++++---- .../views/detail_page/DetailPageLayoutView.js | 1 + .../public/js/views/graph/LineageLayoutView.js | 36 +++- .../js/views/graph/PropagationPropertyModal.js | 184 +++++++++++++++++-- 6 files changed, 257 insertions(+), 48 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/atlas/blob/45bf48e6/dashboardv2/public/css/scss/override.scss ---------------------------------------------------------------------- diff --git a/dashboardv2/public/css/scss/override.scss b/dashboardv2/public/css/scss/override.scss index c3ee8b1..1815c14 100644 --- a/dashboardv2/public/css/scss/override.scss +++ b/dashboardv2/public/css/scss/override.scss @@ -429,4 +429,7 @@ div.columnmanager-dropdown-container { .fa-color { color: $color_keppel_approx +} +.w30{ + width: 30% !important; } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/atlas/blob/45bf48e6/dashboardv2/public/css/scss/theme.scss ---------------------------------------------------------------------- diff --git a/dashboardv2/public/css/scss/theme.scss b/dashboardv2/public/css/scss/theme.scss index 4848673..a820dd6 100644 --- a/dashboardv2/public/css/scss/theme.scss +++ b/dashboardv2/public/css/scss/theme.scss @@ -137,14 +137,17 @@ header { a { color: $color_jungle_green_approx; + cursor: pointer; &:focus { color: $color_puerto_rico_approx; text-decoration: none; outline: none; + cursor: pointer; } &:hover { color: $color_puerto_rico_approx; text-decoration: none; + cursor: pointer; } } http://git-wip-us.apache.org/repos/asf/atlas/blob/45bf48e6/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 index 1599858..1d008a9 100644 --- a/dashboardv2/public/js/templates/graph/PropagationPropertyModalView_tmpl.html +++ b/dashboardv2/public/js/templates/graph/PropagationPropertyModalView_tmpl.html @@ -15,38 +15,54 @@ * 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 class="col-sm-12"> + <div class="row"> + <div class="col-sm-9" style="margin-top: 5px;"> + <span class="pull-left">Propagation flow</span> + <label class="switch pull-left"> + <input type="checkbox" class="switch-input" name="editPropagationType" value="text"> + <span class="switch-slider"></span> + </label> + <span class="pull-left">Block propagation</span> + </div> </div> + <hr style="margin-top: 0px;"> </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 class="editPropagation col-sm-12"> + <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> + <div data-id="PropagatedClassificationTable" class="propagatedClassificationTable col-sm-12" style="display: none"></div> </div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/atlas/blob/45bf48e6/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 eb17504..d0b7009 100644 --- a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js +++ b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js @@ -242,6 +242,7 @@ define(['require', this.renderLineageLayoutView({ guid: this.id, entityDefCollection: this.entityDefCollection, + fetchCollection: this.fetchCollection.bind(this), actionCallBack: function() { that.$('#expand_collapse_panel').click(); } http://git-wip-us.apache.org/repos/asf/atlas/blob/45bf48e6/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 c1d8a9c..0d95f0c 100644 --- a/dashboardv2/public/js/views/graph/LineageLayoutView.js +++ b/dashboardv2/public/js/views/graph/LineageLayoutView.js @@ -56,7 +56,7 @@ define(['require', * @constructs */ initialize: function(options) { - _.extend(this, _.pick(options, 'guid', 'entityDefCollection', 'actionCallBack')); + _.extend(this, _.pick(options, 'guid', 'entityDefCollection', 'actionCallBack', 'fetchCollection')); this.collection = new VLineageList(); this.lineageData = null; this.typeMap = {}; @@ -68,6 +68,9 @@ define(['require', var that = this; this.$('.fontLoader').show(); this.fetchGraphData(); + if (platform.name === "IE") { + this.$('svg').css('opacity', '0'); + } if (this.layoutRendered) { this.layoutRendered(); } @@ -180,6 +183,14 @@ define(['require', }); } }, + toggleInformationSlider: function(options) { + if (options.open && !this.$('.lineage-edge-details').hasClass("open")) { + this.$('.lineage-edge-details').addClass('open'); + } else if (options.close && this.$('.lineage-edge-details').hasClass("open")) { + d3.selectAll('circle').attr("stroke", "none"); + this.$('.lineage-edge-details').removeClass('open'); + } + }, setGraphZoomPositionCal: function(argument) { var initialScale = 1.2, svgEl = this.$('svg'), @@ -371,6 +382,9 @@ define(['require', svg.call(zoom) .call(tooltip); + if (platform.name !== "IE") { + this.$('.fontLoader').hide(); + } render(svgGroup, this.g); svg.on("dblclick.zoom", null) .on("wheel.zoom", null); @@ -429,7 +443,8 @@ define(['require', edgeInfo: data, relationshipId: relationshipId, lineageData: that.lineageData, - apiGuid: that.apiGuid + apiGuid: that.apiGuid, + detailPageFetchCollection: that.fetchCollection }); }); }) @@ -446,6 +461,23 @@ define(['require', this.setGraphZoomPositionCal(); zoom.event(svg); //svg.attr('height', this.g.graph().height * initialScale + 40); + if (platform.name === "IE") { + this.IEGraphRenderDone = 0; + this.$('svg .edgePath').each(function(argument) { + var childNode = $(this).find('marker'); + $(this).find('marker').remove(); + var eleRef = this; + ++that.IEGraphRenderDone; + setTimeout(function(argument) { + $(eleRef).find('defs').append(childNode); + --that.IEGraphRenderDone; + if (that.IEGraphRenderDone === 0) { + this.$('.fontLoader').hide(); + this.$('svg').fadeTo(1000, 1) + } + }, 1000); + }); + } } }); return LineageLayoutView; http://git-wip-us.apache.org/repos/asf/atlas/blob/45bf48e6/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 index 76d62ef..0791eea 100644 --- a/dashboardv2/public/js/views/graph/PropagationPropertyModal.js +++ b/dashboardv2/public/js/views/graph/PropagationPropertyModal.js @@ -19,11 +19,12 @@ define(['require', 'hbs!tmpl/graph/PropagationPropertyModalView_tmpl', 'models/VRelationship', + 'models/VEntity', 'modules/Modal', 'utils/Utils', 'utils/UrlLinks', 'utils/Messages' -], function(require, PropagationPropertyModalViewTmpl, VRelationship, Modal, Utils, UrlLinks, Messages) { +], function(require, PropagationPropertyModalViewTmpl, VRelationship, VEntity, Modal, Utils, UrlLinks, Messages) { 'use strict'; var PropogationPropertyModal = Backbone.Marionette.CompositeView.extend({ @@ -32,12 +33,78 @@ define(['require', regions: {}, ui: { propagationOptions: '[data-id="propagationOptions"]', - edgeDetailName: '[data-id="edgeDetailName"]' + edgeDetailName: '[data-id="edgeDetailName"]', + propagationState: "[data-id='propagationState']", + classificationClick: "[data-id='classificationClick']", + editPropagationType: 'input[name="editPropagationType"]', + PropagatedClassificationTable: "[data-id='PropagatedClassificationTable']" + }, events: function() { - var events = {}; + var events = {}, + that = this; events["change " + this.ui.propagationOptions] = function() { + this.modalEdited = true; + this.modal.$el.find('button.ok').attr("disabled", false); + }; + events["click " + this.ui.editPropagationType] = function(e) { + if (this.modalEdited === true) { + e.preventDefault(); + that.notifyModal(); + } + }; + events["change " + this.ui.editPropagationType] = function(e) { + if (e.target.checked) { + this.showPropagatedClassificationTable(); + this.viewType = "table"; + } else { + this.showEditPropagation(); + this.viewType = "flow"; + } + }; + events["click " + this.ui.classificationClick] = function(e) { + var that = this, + url = "", + notifyObj = { + modal: true, + text: "Are you sure you want to navigate away from this page ?", + ok: function(argument) { + that.modal.trigger('cancel'); + Utils.setUrl({ + url: url, + mergeBrowserUrl: false, + trigger: true + }); + + }, + cancel: function(argument) {} + }; + if (e.currentTarget.dataset.entityguid) { + url = '#!/tag/tagAttribute/' + e.currentTarget.dataset.entityguid; + } else { + url = '#!/detailPage/' + e.currentTarget.dataset.guid + '?tabActive=lineage'; + } + Utils.notifyConfirm(notifyObj); + }; + events["change " + this.ui.propagationState] = function(e) { + this.modalEdited = true; this.modal.$el.find('button.ok').attr("disabled", false); + var entityguid = e.currentTarget.dataset.entityguid; + if (e.target.checked) { + this.propagatedClassifications = _.reject(this.propagatedClassifications, function(val, key) { + if (val.entityGuid == entityguid) { + that.blockedPropagatedClassifications.push(val); + return true; + } + }); + } else { + this.blockedPropagatedClassifications = _.reject(this.blockedPropagatedClassifications, function(val, key) { + if (val.entityGuid == entityguid) { + that.propagatedClassifications.push(val); + return true; + } + }); + } }; return events; }, @@ -46,8 +113,11 @@ define(['require', * @constructs */ initialize: function(options) { - _.extend(this, _.pick(options, 'edgeInfo', 'relationshipId', 'lineageData', 'apiGuid')); + _.extend(this, _.pick(options, 'edgeInfo', 'relationshipId', 'lineageData', 'apiGuid', 'detailPageFetchCollection')); this.entityModel = new VRelationship(); + this.VEntityModel = new VEntity(); + this.modalEdited = false; + this.viewType = 'flow'; var that = this, modalObj = { title: 'Edit Propagation Flow', @@ -55,7 +125,7 @@ define(['require', okText: 'Update', okCloses: false, cancelText: "Cancel", - mainClass: 'modal-md', + mainClass: 'modal-lg', allowCancel: true, }; @@ -71,9 +141,7 @@ define(['require', this.updateEdgeView(this.edgeInfo); }, - onRender: function() { - - }, + onRender: function() {}, updateEdgeView: function(options) { var obj = options.obj, fromEntity = this.lineageData.guidEntityMap[obj.fromEntityId], @@ -124,6 +192,8 @@ define(['require', "relationshipData": this.apiGuid[id], "graphData": options }) + "]").prop('checked', true); + this.showBlockedClassificationTable(this.apiGuid[id]); + this.getEntityNameForClassification(this.apiGuid[id]); } else { if (this.edgeCall && this.edgeCall.readyState != 4) { this.edgeCall.abort(); @@ -137,6 +207,8 @@ define(['require', "relationshipData": relationshipData, "graphData": options }) + "]").prop('checked', true); + that.showBlockedClassificationTable(relationshipData); + that.getEntityNameForClassification(relationshipData); that.hideLoader({ buttonDisabled: true }); } }, @@ -149,17 +221,29 @@ define(['require', updateRelation: function() { var that = this, entityId = that.ui.propagationOptions.attr('entity-id'), - PropagationValue = this.$("input[name='propagateRelation']:checked").val(); + PropagationValue = this.$("input[name='propagateRelation']:checked").val(), + relationshipProp = {}; if (PropagationValue === this.ui.propagationOptions.attr("propagation")) { return; } this.ui.propagationOptions.attr("propagation", PropagationValue); - var relationshipProp = { - "propagateTags": that.getPropagationFlow({ - "relationshipData": _.extend(that.apiGuid[entityId], { 'propagateTags': PropagationValue }), - "graphData": { from: { guid: this.edgeInfo.obj.fromEntityId } } - }) - }; + if (this.viewType == "flow") { + relationshipProp = { + "propagateTags": that.getPropagationFlow({ + "relationshipData": _.extend(that.apiGuid[entityId], { 'propagateTags': PropagationValue }), + "graphData": { from: { guid: this.edgeInfo.obj.fromEntityId } } + }) + } + } else { + relationshipProp = { + "blockedPropagatedClassifications": _.uniq(that.blockedPropagatedClassifications, function(val, key) { + return val.entityGuid; + }), + "propagatedClassifications": _.uniq(that.propagatedClassifications, function(val, key) { + return val.entityGuid; + }) + }; + } this.showLoader(); this.entityModel.saveRelationship({ data: JSON.stringify(_.extend(that.apiGuid[entityId], relationshipProp)), @@ -168,6 +252,7 @@ define(['require', that.hideLoader({ buttonDisabled: true }); that.modal.trigger('cancel'); that.apiGuid[relationshipData.guid] = relationshipData; + that.detailPageFetchCollection(); Utils.notifySuccess({ content: "Propagation flow updated succesfully." }); @@ -178,6 +263,48 @@ define(['require', } }); }, + showBlockedClassificationTable: function(options) { + var that = this, + propagationStringValue = "", + classificationTableValue = ""; + this.blockedPropagatedClassifications = _.isUndefined(options.blockedPropagatedClassifications) ? [] : options.blockedPropagatedClassifications; + this.propagatedClassifications = _.isUndefined(options.propagatedClassifications) ? [] : options.propagatedClassifications; + _.each(this.blockedPropagatedClassifications, function(val, key) { + propagationStringValue += "<tr><td class='html-cell string-cell renderable text-center w30'><a data-id='classificationClick' title='' data-entityGuid=" + val.entityGuid + ">" + val.typeName + "</a></td><td class='html-cell string-cell renderable text-center' data-tr-entityGuid=" + val.entityGuid + "></td><td class='html-cell string-cell renderable text-center w30'><input type='checkbox' checked data-id='propagationState' data-entityGuid=" + val.entityGuid + " class='input'></td></tr>"; + }); + _.each(this.propagatedClassifications, function(val, key) { + propagationStringValue += "<tr><td class='html-cell string-cell renderable text-center w30'><a data-id='classificationClick' title='' data-entityGuid=" + val.entityGuid + ">" + val.typeName + "</a></td><td class='html-cell string-cell renderable text-center' data-tr-entityGuid=" + val.entityGuid + "></td><td class='html-cell string-cell renderable text-center w30'><input type='checkbox' data-id='propagationState' data-entityGuid=" + val.entityGuid + " class='input'></td></tr>"; + }); + + classificationTableValue = "<table class='attriTable'><caption>Block Propagatation Table</caption><tr><th class='html-cell string-cell renderable w30'>Classification</th><th class='html-cell string-cell renderable'>Entity Name</th><th class='html-cell string-cell renderable w30'>Block Propagatation</th>" + propagationStringValue + "</table>"; + + this.ui.PropagatedClassificationTable.append(_.isEmpty(propagationStringValue) ? "No Records Found." : classificationTableValue); + }, + getEntityNameForClassification: function(options) { + var that = this, + allEntityGuid = _.pluck(_.union(options.blockedPropagatedClassifications, options.propagatedClassifications, function(val, key) { + return val.entityGuid; + }), 'entityGuid'), + apiCall = allEntityGuid.length; + _.map(allEntityGuid, function(entityGuid, key) { + that.VEntityModel.getEntity(entityGuid, { + success: function(data) { + var entityNameWithType = Utils.getName(data['entity']) + ' ( ' + data['entity'].typeName + ' )', + link = "<a data-id='classificationClick' title='' data-guid=" + data['entity'].guid + ">" + entityNameWithType + "</a>"; + that.ui.PropagatedClassificationTable.find('[data-tr-entityGuid=' + entityGuid + ']').html(link); + }, + complete: function() { + apiCall -= 1; + if (apiCall == 0) { + that.hideLoader({ buttonDisabled: true }); + } + }, + cust_error: function() { + that.hideLoader({ buttonDisabled: true }); + } + }); + }); + }, showLoader: function() { this.modal.$el.find('button.ok').attr("disabled", true); this.$('.overlay').removeClass('hide').addClass('show'); @@ -186,7 +313,34 @@ define(['require', var buttonDisabled = options && options.buttonDisabled; this.modal.$el.find('button.ok').attr("disabled", buttonDisabled ? buttonDisabled : false); this.$('.overlay').removeClass('show').addClass('hide'); + }, + notifyModal: function(options) { + var that = this, + notifyObj = { + modal: true, + text: "It looks like you have been edited something. If you leave before saving, your changes will be lost.", + ok: function(argument) { + that.viewType = that.ui.editPropagationType.is(":checked") ? "flow" : "table"; + that.ui.editPropagationType.prop("checked", that.viewType === "flow" ? false : true).trigger("change"); + that.modal.$el.find('button.ok').attr("disabled", true); + }, + cancel: function(argument) { + that.viewType = that.ui.editPropagationType.is(":checked") ? "table" : "flow"; + } + }; + Utils.notifyConfirm(notifyObj); + }, + showEditPropagation: function() { + this.$('.editPropagation').show(); + this.$('.propagatedClassificationTable').hide(); + this.modal.$el.find('.modal-title').text("Edit Propagation Flow"); + }, + showPropagatedClassificationTable: function() { + this.$('.editPropagation').hide(); + this.$('.propagatedClassificationTable').show(); + this.modal.$el.find('.modal-title').text("Block Propagation Table"); } + }); return PropogationPropertyModal; }); \ No newline at end of file
