You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by kb...@apache.org on 2018/10/10 14:12:17 UTC

atlas git commit: ATLAS-2820: UI : Add replication audits tab for AtlasCluster entity to show Export & Import audit

Repository: atlas
Updated Branches:
  refs/heads/master 21fcc7e12 -> ab2043a80


ATLAS-2820: UI : Add replication audits tab for AtlasCluster entity to show Export & Import audit

Signed-off-by: kevalbhatt <kb...@apache.org>


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

Branch: refs/heads/master
Commit: ab2043a8005f6b4048f825bdae75a140c17d6a3e
Parents: 21fcc7e
Author: Abhishek Kadam <ab...@gmail.com>
Authored: Wed Oct 10 19:29:18 2018 +0530
Committer: kevalbhatt <kb...@apache.org>
Committed: Wed Oct 10 19:41:42 2018 +0530

----------------------------------------------------------------------
 dashboardv2/public/js/collection/VSearchList.js |  10 +
 .../ReplicationAuditTableLayoutView_tmpl.html   |  20 ++
 .../public/js/templates/common/Modal.html       |   2 +-
 .../js/templates/common/TableLayout_tmpl.html   |  50 ++++
 .../detail_page/DetailPageLayoutView_tmpl.html  |   8 +
 dashboardv2/public/js/utils/TableLayout.js      | 260 +++++++++++++++++--
 dashboardv2/public/js/utils/UrlLinks.js         |  23 ++
 .../audit/ReplicationAuditTableLayoutView.js    | 220 ++++++++++++++++
 .../views/detail_page/DetailPageLayoutView.js   |  12 +
 .../js/views/search/SearchResultLayoutView.js   |   2 +-
 10 files changed, 582 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/atlas/blob/ab2043a8/dashboardv2/public/js/collection/VSearchList.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/collection/VSearchList.js b/dashboardv2/public/js/collection/VSearchList.js
index 7417efc..e708b23 100644
--- a/dashboardv2/public/js/collection/VSearchList.js
+++ b/dashboardv2/public/js/collection/VSearchList.js
@@ -60,6 +60,16 @@ define(['require',
                     return [];
                 }
             },
+            getExpimpAudit: function(params, options) {
+                var url = UrlLinks.expimpAudit(params);
+
+                options = _.extend({
+                    contentType: 'application/json',
+                    dataType: 'json',
+                }, options);
+
+                return this.constructor.nonCrudOperation.call(this, url, 'GET', options);
+            },
             getBasicRearchResult: function(options) {
                 var url = UrlLinks.searchApiUrl('basic');
 

http://git-wip-us.apache.org/repos/asf/atlas/blob/ab2043a8/dashboardv2/public/js/templates/audit/ReplicationAuditTableLayoutView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/audit/ReplicationAuditTableLayoutView_tmpl.html b/dashboardv2/public/js/templates/audit/ReplicationAuditTableLayoutView_tmpl.html
new file mode 100644
index 0000000..fec21f8
--- /dev/null
+++ b/dashboardv2/public/js/templates/audit/ReplicationAuditTableLayoutView_tmpl.html
@@ -0,0 +1,20 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<div>
+    <div class="tableOverlay"></div>
+    <div id="r_replicationAuditTableLayoutView"></div>
+</div>

http://git-wip-us.apache.org/repos/asf/atlas/blob/ab2043a8/dashboardv2/public/js/templates/common/Modal.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/common/Modal.html b/dashboardv2/public/js/templates/common/Modal.html
index 2179a7d..6327241 100644
--- a/dashboardv2/public/js/templates/common/Modal.html
+++ b/dashboardv2/public/js/templates/common/Modal.html
@@ -28,7 +28,7 @@
                 </h4>
         </div>
         {{/if}} {{#if contentWithFooter}} {{else}}
-        <div class="modal-body">{{#if contentHtml}} {{{contentHtm}}} {{else}} {{content}} {{/if}}
+        <div class="modal-body">{{#if contentHtml}} {{{content}}} {{else}} {{content}} {{/if}}
         </div>
         {{#if showFooter}}
         <div class="modal-footer">

http://git-wip-us.apache.org/repos/asf/atlas/blob/ab2043a8/dashboardv2/public/js/templates/common/TableLayout_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/common/TableLayout_tmpl.html b/dashboardv2/public/js/templates/common/TableLayout_tmpl.html
index 99bc93d..82d6c39 100644
--- a/dashboardv2/public/js/templates/common/TableLayout_tmpl.html
+++ b/dashboardv2/public/js/templates/common/TableLayout_tmpl.html
@@ -26,6 +26,12 @@
     <div class="clearfix banded">
         <div data-id="r_footerRecords" class="margin-top-10"></div>
     </div>
+    {{/if}} {{#if includeAtlasPagination}}
+    <div class="row form-group pagination-box filter-box">
+        <div class="col-sm-4">
+            <span class="labelShowRecord pull-left" data-id="pageRecordText"> </span>
+        </div>
+    </div>
     {{/if}}
     <div class="position-relative thick-border">
         <div data-id="r_tableList" class="table-responsive tableBorder"> </div>
@@ -53,5 +59,49 @@
             </div>
         </div>
     </div>
+    {{/if}} {{#if includeAtlasPagination}}
+    <div class="row pagination-box">
+        <div class="col-sm-offset-4 col-sm-8">
+            <div class="inline-content-fr">
+                <div class="backgrid-paginator inline">
+                    <ul class="" data-id="paginationDiv" style="display:none">
+                        <li>
+                            <button type="button" data-id="previousData" title="Previous" disabled=true>
+                                <i class="fa fa-angle-left" aria-hidden="true"></i>
+                            </button>
+                        </li>
+                        <li class="active">
+                            <a href="javascript:void(0)" data-id="activePage"></a>
+                        </li>
+                        <li>
+                            <button type="button" data-id="nextData" title="Next">
+                                <i class="fa fa-angle-right" aria-hidden="true"></i>
+                            </button>
+                        </li>
+                    </ul>
+                </div>
+                {{#if includeAtlasGotoPage}}
+                <div class="inline col-sm-4" data-id="paginationDiv" style="display:none">
+                    <div class="input-group" data-id="goToPageDiv">
+                        <input type="text" class="form-control number-input" data-id="gotoPage" placeholder="Goto Page" />
+                        <span class="input-group-btn">
+                            <button class="btn btn-default" type="button" data-id="gotoPagebtn" title="Goto Page" disabled="disabled">Go!</button>
+                        </span>
+                    </div>
+                </div>
+                {{/if}} {{#if includeAtlasPageSize}}
+                <div class="inline">
+                    <div class="form-group inline-content">
+                        <span class="control-label-sm inline ">Page Limit :</span>
+                        <div class="inline" style="width: 80px;">
+                            <select data-id="showPage" multiple="multiple" class="form-control">
+                            </select>
+                        </div>
+                    </div>
+                </div>
+                {{/if}}
+            </div>
+        </div>
+    </div>
     {{/if}}
 </div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/atlas/blob/ab2043a8/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
index a968c62..5bb9415 100644
--- a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
@@ -52,6 +52,7 @@
                 <li role="relationship" class="tab"><a href="#tab-relationship" aria-controls="tab-relationship" role="tab" data-toggle="tab">Relationships</a></li>
                 <li role="classification"><a href="#tab-tagTable" aria-controls="tab-tagTable" role="tab" data-toggle="tab">Classifications</a></li>
                 <li role="audit" class="tab"><a href="#tab-audit" aria-controls="tab-audit" role="tab" data-toggle="tab">Audits</a></li>
+                <li role="raudits" class="tab replicationTab" style="display:none"><a href="#tab-raudit" aria-controls="tab-raudit" role="tab" data-toggle="tab">Export/Import Audits</a></li>
                 <li role="schema" class="tab schemaTable" style="display:none"><a href="#tab-schema" aria-controls="tab-schema" role="tab" data-toggle="tab">Schema</a></li>
                 <li role="profile" class="tab profileTab" style="display:none"><a href="#tab-profile" aria-controls="tab-profile" role="tab" data-toggle="tab">Profile</a></li>
             </ul>
@@ -99,6 +100,13 @@
                 </div>
             </div>
         </div>
+        <div id="tab-raudit" role="raudits" class="tab-pane">
+            <div id="r_replicationAuditTableLayoutView">
+                <div class="fontLoader-relative">
+                    <i class="fa fa-refresh fa-spin-custom"></i>
+                </div>
+            </div>
+        </div>
         <div id="tab-schema" role="schema" class="tab-pane animated fadeIn">
             <div id="r_schemaTableLayoutView">
                 <div class="fontLoader-relative">

http://git-wip-us.apache.org/repos/asf/atlas/blob/ab2043a8/dashboardv2/public/js/utils/TableLayout.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/TableLayout.js b/dashboardv2/public/js/utils/TableLayout.js
index a2ba0a6..2113832 100644
--- a/dashboardv2/public/js/utils/TableLayout.js
+++ b/dashboardv2/public/js/utils/TableLayout.js
@@ -22,13 +22,15 @@
 define(['require',
     'backbone',
     'hbs!tmpl/common/TableLayout_tmpl',
+    'utils/Messages',
+    'utils/Utils',
     'backgrid-filter',
     'backgrid-paginator',
     'backgrid-sizeable',
     'backgrid-orderable',
     'backgrid-select-all',
     'backgrid-columnmanager'
-], function(require, Backbone, FSTablelayoutTmpl) {
+], function(require, Backbone, FSTablelayoutTmpl, Messages, Utils) {
     'use strict';
 
     var FSTableLayout = Backbone.Marionette.LayoutView.extend(
@@ -51,7 +53,15 @@ define(['require',
 
             // /** ui selector cache */
             ui: {
-                selectPageSize: 'select[data-id="pageSize"]'
+                selectPageSize: 'select[data-id="pageSize"]',
+                paginationDiv: '[data-id="paginationDiv"]',
+                previousData: "[data-id='previousData']",
+                nextData: "[data-id='nextData']",
+                pageRecordText: "[data-id='pageRecordText']",
+                showPage: "[data-id='showPage']",
+                gotoPage: "[data-id='gotoPage']",
+                gotoPagebtn: "[data-id='gotoPagebtn']",
+                activePage: "[data-id='activePage']"
             },
 
             gridOpts: {
@@ -113,6 +123,8 @@ define(['require',
 
             includePagination: true,
 
+            includeAtlasPagination: false,
+
             includeFilter: false,
 
             includeHeaderSearch: false,
@@ -132,8 +144,26 @@ define(['require',
 
             /** ui events hash */
             events: function() {
-                var events = {};
+                var events = {},
+                    that = this;
                 events['change ' + this.ui.selectPageSize] = 'onPageSizeChange';
+                events["click " + this.ui.nextData] = "onClicknextData";
+                events["click " + this.ui.previousData] = "onClickpreviousData";
+                events["click " + this.ui.gotoPagebtn] = 'gotoPagebtn';
+                events["keyup " + this.ui.gotoPage] = function(e) {
+                    var code = e.which,
+                        goToPage = parseInt(e.currentTarget.value);
+                    if (e.currentTarget.value) {
+                        that.ui.gotoPagebtn.attr('disabled', false);
+                    } else {
+                        that.ui.gotoPagebtn.attr('disabled', true);
+                    }
+                    if (code == 13) {
+                        if (e.currentTarget.value) {
+                            that.gotoPagebtn();
+                        }
+                    }
+                };
                 return events;
             },
 
@@ -142,10 +172,11 @@ define(['require',
              * @constructs
              */
             initialize: function(options) {
-                _.extend(this, _.pick(options, 'collection', 'columns', 'includePagination',
-                    'includeHeaderSearch', 'includeFilter', 'includePageSize',
-                    'includeFooterRecords', 'includeColumnManager', 'includeSizeAbleColumns', 'includeOrderAbleColumns', 'includeTableLoader'));
-
+                this.limit = 25;
+                this.offset = 0;
+                _.extend(this, _.pick(options, 'collection', 'columns', 'includePagination', 'includeHeaderSearch', 'includeFilter', 'includePageSize',
+                    'includeFooterRecords', 'includeColumnManager', 'includeSizeAbleColumns', 'includeOrderAbleColumns', 'includeTableLoader', 'includeAtlasPagination', 'atlasPaginationOpts'));
+                _.extend(this, this.atlasPaginationOpts);
                 _.extend(this.gridOpts, options.gridOpts, { collection: this.collection, columns: this.columns });
                 _.extend(this.filterOpts, options.filterOpts);
                 _.extend(this.paginatorOpts, options.paginatorOpts);
@@ -164,13 +195,17 @@ define(['require',
                     this.$('div[data-id="r_tableSpinner"]').removeClass('show');
                 }, this);
 
-                this.listenTo(this.collection, 'reset', function(collection, response) {
+                this.listenTo(this.collection, 'reset', function(collection, options) {
+                    this.$('div[data-id="r_tableSpinner"]').removeClass('show');
                     if (this.includePagination) {
                         this.renderPagination();
                     }
                     if (this.includeFooterRecords) {
                         this.renderFooterRecords(this.collection.state);
                     }
+                    if (this.includeAtlasPagination) {
+                        this.renderAtlasPagination(options);
+                    }
                 }, this);
 
                 /*This "sort" trigger event is fired when clicked on
@@ -184,6 +219,17 @@ define(['require',
                 this.listenTo(this.collection, "backgrid:sort", function() {
                     this.collection.trigger("sort");
                 });
+                this.listenTo(this, "grid:refresh", function() {
+                    if (this.grid) {
+                        this.grid.trigger("backgrid:refresh");
+                    }
+                });
+                this.listenTo(this, "grid:refresh:update", function() {
+                    if (this.grid) {
+                        this.grid.trigger("backgrid:refresh");
+                        if (this.grid.collection) { this.grid.collection.trigger("backgrid:colgroup:updated"); }
+                    }
+                });
 
                 // It will show tool tip when td has ellipsis  Property
                 this.listenTo(this.collection, "backgrid:refresh", function() {
@@ -203,6 +249,9 @@ define(['require',
                 if (this.includePagination) {
                     this.renderPagination();
                 }
+                if (this.includeAtlasPagination) {
+                    this.renderAtlasPagination();
+                }
                 if (this.includeFilter) {
                     this.renderFilter();
                 }
@@ -212,12 +261,6 @@ define(['require',
                 if (this.includeColumnManager) {
                     this.renderColumnManager();
                 }
-                if (this.includeSizeAbleColumns) {
-                    this.renderSizeAbleColumns();
-                }
-                if (this.includeOrderAbleColumns) {
-                    this.renderOrderAbleColumns();
-                }
                 if (this.includePageSize) {
                     this.ui.selectPageSize.select2({
                         data: _.sortBy(_.union([25, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500], [this.collection.state.pageSize])),
@@ -234,11 +277,20 @@ define(['require',
              */
             renderTable: function() {
                 var that = this;
-                this.rTableList.show(new Backgrid.Grid(this.gridOpts).on('backgrid:rendered', function() {
-                    that.trigger('backgrid:rendered', this)
-                }));
-            },
+                this.grid = new Backgrid.Grid(this.gridOpts).on('backgrid:rendered', function() {
+                    that.trigger('backgrid:manual:rendered', this)
+                });
 
+                this.rTableList.show(this.grid);
+            },
+            onShow: function() {
+                if (this.includeSizeAbleColumns) {
+                    this.renderSizeAbleColumns();
+                }
+                if (this.includeOrderAbleColumns) {
+                    this.renderOrderAbleColumns();
+                }
+            },
             /**
              * show pagination buttons(first, last, next, prev and numbers)
              */
@@ -256,6 +308,74 @@ define(['require',
                 }
             },
 
+            renderAtlasPagination: function(options) {
+                var isFirstPage = this.offset === 0,
+                    dataLength = this.collection.length,
+                    goToPage = this.ui.gotoPage.val();
+
+                if (!dataLength && this.offset >= this.limit && ((options && options.next) || goToPage) && (options && !options.fromUrl)) {
+                    /* User clicks on next button and server returns
+                    empty response then disabled the next button without rendering table*/
+
+                    var pageNumber = this.activePage + 1;
+                    if (goToPage) {
+                        pageNumber = goToPage;
+                        this.offset = (this.activePage - 1) * this.limit;
+                    } else {
+                        this.ui.nextData.attr('disabled', true);
+                        this.offset = this.offset - this.limit;
+                    }
+                    if (this.value) {
+                        this.value.pageOffset = this.offset;
+                        if (this.triggerUrl) {
+                            this.triggerUrl();
+                        }
+                    }
+                    Utils.notifyInfo({
+                        html: true,
+                        content: Messages.search.noRecordForPage + '<b>' + Utils.getNumberSuffix({ number: pageNumber, sup: true }) + '</b> page'
+                    });
+                    return;
+                }
+
+                /*Next button check.
+                It's outside of Previous button else condition
+                because when user comes from 2 page to 1 page than we need to check next button.*/
+                if (dataLength < this.limit) {
+                    this.ui.nextData.attr('disabled', true);
+                } else {
+                    this.ui.nextData.attr('disabled', false);
+                }
+
+                if (isFirstPage && (!dataLength || dataLength < this.limit)) {
+                    this.ui.paginationDiv.hide();
+                } else {
+                    this.ui.paginationDiv.show();
+                }
+
+                // Previous button check.s
+                if (isFirstPage) {
+                    this.ui.previousData.attr('disabled', true);
+                    this.pageFrom = 1;
+                    this.pageTo = this.limit;
+                } else {
+                    this.ui.previousData.attr('disabled', false);
+                }
+
+                if (options && options.next) {
+                    //on next click, adding "1" for showing the another records.
+                    this.pageTo = this.offset + this.limit;
+                    this.pageFrom = this.offset + 1;
+                } else if (!isFirstPage && options && options.previous) {
+                    this.pageTo = this.pageTo - this.limit;
+                    this.pageFrom = (this.pageTo - this.limit) + 1;
+                }
+                this.ui.pageRecordText.html("Showing  <u>" + this.collection.length + " records</u> From " + this.pageFrom + " - " + this.pageTo);
+                this.activePage = Math.round(this.pageTo / this.limit);
+                this.ui.activePage.attr('title', "Page " + this.activePage);
+                this.ui.activePage.text(this.activePage);
+            },
+
             /**
              * show/hide pagination buttons of the grid
              */
@@ -329,11 +449,12 @@ define(['require',
 
             renderSizeAbleColumns: function() {
                 // Add sizeable columns
-                var sizeAbleCol = new Backgrid.Extension.SizeAbleColumns({
-                    collection: this.collection,
-                    columns: this.columns,
-                    grid: this.getGridObj()
-                });
+                var that = this,
+                    sizeAbleCol = new Backgrid.Extension.SizeAbleColumns({
+                        collection: this.collection,
+                        columns: this.columns,
+                        grid: this.getGridObj()
+                    });
                 this.$('thead').before(sizeAbleCol.render().el);
 
                 // Add resize handlers
@@ -399,6 +520,99 @@ define(['require',
                         });
                     }
                 }
+            },
+            onClicknextData: function() {
+                this.offset = this.offset + this.limit;
+                _.extend(this.collection.queryParams, {
+                    offset: this.offset
+                });
+                if (this.value) {
+                    this.value.pageOffset = this.offset;
+                    if (this.triggerUrl) {
+                        this.triggerUrl();
+                    }
+                }
+                this.ui.gotoPage.val('');
+                this.ui.gotoPage.parent().removeClass('has-error');
+                if (this.fetchCollection) {
+                    this.fetchCollection({
+                        next: true
+                    });
+                }
+            },
+            onClickpreviousData: function() {
+                this.offset = this.offset - this.limit;
+                if (this.offset <= -1) {
+                    this.offset = 0;
+                }
+                _.extend(this.collection.queryParams, {
+                    offset: this.offset
+                });
+                if (this.value) {
+                    this.value.pageOffset = this.offset;
+                    if (this.triggerUrl) {
+                        this.triggerUrl();
+                    }
+                }
+                this.ui.gotoPage.val('');
+                this.ui.gotoPage.parent().removeClass('has-error');
+                if (this.fetchCollection) {
+                    this.fetchCollection({
+                        previous: true
+                    });
+                }
+            },
+            // TODO : Need to add pageLimit for atlasPagination
+            changePageLimit: function(e, obj) {
+                if (!obj || (obj && !obj.skipViewChange)) {
+                    var limit = parseInt(this.ui.showPage.val());
+                    if (limit == 0) {
+                        this.ui.showPage.data('select2').$container.addClass('has-error');
+                        return;
+                    } else {
+                        this.ui.showPage.data('select2').$container.removeClass('has-error');
+                    }
+                    this.limit = limit;
+                    this.offset = 0;
+                    if (this.value) {
+                        this.value.pageLimit = this.limit;
+                        this.value.pageOffset = this.offset;
+                        if (this.triggerUrl) {
+                            this.triggerUrl();
+                        }
+                    }
+                    this.ui.gotoPage.val('');
+                    this.ui.gotoPage.parent().removeClass('has-error');
+                    _.extend(this.collection.queryParams, { limit: this.limit, offset: this.offset });
+                    this.fetchCollection();
+                }
+            },
+            gotoPagebtn: function(e) {
+                var that = this;
+                var goToPage = parseInt(this.ui.gotoPage.val());
+                if (!(_.isNaN(goToPage) || goToPage <= -1)) {
+                    this.offset = (goToPage - 1) * this.limit;
+                    if (this.offset <= -1) {
+                        this.offset = 0;
+                    }
+                    _.extend(this.collection.queryParams, { limit: this.limit, offset: this.offset });
+                    if (this.offset == (this.pageFrom - 1)) {
+                        Utils.notifyInfo({
+                            content: Messages.search.onSamePage
+                        });
+                    } else {
+                        if (this.value) {
+                            this.value.pageOffset = this.offset;
+                            if (this.triggerUrl) {
+                                this.triggerUrl();
+                            }
+                        }
+                        // this.offset is updated in gotoPagebtn function so use next button calculation.
+                        if (this.fetchCollection) {
+                            this.fetchCollection({ 'next': true });
+                        }
+                    }
+                }
             }
         });
 

http://git-wip-us.apache.org/repos/asf/atlas/blob/ab2043a8/dashboardv2/public/js/utils/UrlLinks.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/UrlLinks.js b/dashboardv2/public/js/utils/UrlLinks.js
index 66f2ebe..d3d2a58 100644
--- a/dashboardv2/public/js/utils/UrlLinks.js
+++ b/dashboardv2/public/js/utils/UrlLinks.js
@@ -84,6 +84,29 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
         entityCollectionaudit: function(guid) {
             return this.baseUrlV2 + '/entity/' + guid + '/audit';
         },
+        expimpAudit: function(options) {
+            var url = this.baseUrl + '/admin/expimp/audit',
+                queryParam = [];
+            if (options) {
+                var serverName = options.serverName,
+                    limit = options.limit,
+                    offset = options.offset;
+            }
+
+            if (serverName) {
+                queryParam.push("serverName=" + serverName);
+            }
+            if (limit) {
+                queryParam.push("limit=" + limit);
+            }
+            if (offset) {
+                queryParam.push("offset=" + offset);
+            }
+            if (queryParam.length > 0) {
+                url = url + "?" + queryParam.join("&");
+            }
+            return url;
+        },
         classicationApiUrl: function(name, guid) {
             var typeUrl = this.typedefsUrl();
             if (name) {

http://git-wip-us.apache.org/repos/asf/atlas/blob/ab2043a8/dashboardv2/public/js/views/audit/ReplicationAuditTableLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/audit/ReplicationAuditTableLayoutView.js b/dashboardv2/public/js/views/audit/ReplicationAuditTableLayoutView.js
new file mode 100644
index 0000000..bddea1d
--- /dev/null
+++ b/dashboardv2/public/js/views/audit/ReplicationAuditTableLayoutView.js
@@ -0,0 +1,220 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+define(['require',
+    'backbone',
+    'hbs!tmpl/audit/ReplicationAuditTableLayoutView_tmpl',
+    'utils/CommonViewFunction',
+    'utils/Utils',
+    'collection/VSearchList',
+    'collection/VEntityList',
+    'utils/Messages',
+    'utils/UrlLinks'
+], function(require, Backbone, ReplicationAuditTableLayoutView_tmpl, CommonViewFunction, Utils, VSearchList, VEntityList, Messages, UrlLinks) {
+    'use strict';
+
+    var ReplicationAuditTableLayoutView = Backbone.Marionette.LayoutView.extend(
+        /** @lends TagDetailTableLayoutView */
+        {
+            _viewName: 'ReplicationAuditTableLayoutView',
+
+            template: ReplicationAuditTableLayoutView_tmpl,
+
+            /** Layout sub regions */
+            regions: {
+                RReplicationAuditTableLayoutView: "#r_replicationAuditTableLayoutView"
+            },
+
+            /** ui selector cache */
+            ui: {
+                auditDetail: "[data-action='audit_detail']",
+            },
+            /** ui events hash */
+            events: function() {
+                var events = {}
+                events["click " + this.ui.auditDetail] = "onClickAuditDetails";
+                return events;
+            },
+            /**
+             * intialize a new TagDetailTableLayoutView Layout
+             * @constructs
+             */
+            initialize: function(options) {
+                _.extend(this, _.pick(options, 'entity', 'entityName', 'attributeDefs'));
+                this.searchCollection = new VSearchList();
+                this.entityModel = new(new VEntityList()).model();
+                this.limit = 25;
+                this.offset = 0;
+                this.name = Utils.getName(this.entity);
+                this.commonTableOptions = {
+                    collection: this.searchCollection,
+                    includePagination: false,
+                    includeAtlasPagination: true,
+                    includeFooterRecords: false,
+                    includeColumnManager: false,
+                    includeOrderAbleColumns: false,
+                    includeSizeAbleColumns: false,
+                    includeTableLoader: true,
+                    atlasPaginationOpts: {
+                        limit: this.limit,
+                        offset: this.offset,
+                        fetchCollection: this.fetchCollection.bind(this),
+                    },
+                    gridOpts: {
+                        emptyText: 'No Record found!',
+                        className: 'table table-hover backgrid table-quickMenu colSort'
+                    },
+                    filterOpts: {},
+                    paginatorOpts: {}
+                };
+            },
+            bindEvents: function() {},
+            onRender: function() {
+                this.renderTableLayoutView();
+            },
+            fetchCollection: function(options) {
+                var that = this;
+
+                this.searchCollection.getExpimpAudit(this.searchCollection.queryParams, {
+                    success: function(response) {
+                        that.searchCollection.reset(response, options);
+                    }
+                });
+            },
+            renderTableLayoutView: function() {
+                var that = this;
+                require(['utils/TableLayout'], function(TableLayout) {
+                    var columnCollection = Backgrid.Columns.extend({
+                        sortKey: "displayOrder",
+                        comparator: function(item) {
+                            return item.get(this.sortKey) || 999;
+                        },
+                        setPositions: function() {
+                            _.each(this.models, function(model, index) {
+                                model.set("displayOrder", index + 1, { silent: true });
+                            });
+                            return this;
+                        }
+                    });
+                    var columns = new columnCollection(that.getColumn());
+                    columns.setPositions().sort();
+                    that.RReplicationAuditTableLayoutView.show(new TableLayout(_.extend({}, that.commonTableOptions, {
+                        columns: columns
+                    })));
+                    _.extend(that.searchCollection.queryParams, { limit: that.limit, offset: that.offset, "serverName": that.name });
+                    that.fetchCollection(_.extend({ 'fromUrl': true }));
+                });
+            },
+            getColumn: function(argument) {
+                var that = this,
+                    col = {};
+
+                col['operation'] = {
+                    label: "Operation",
+                    cell: "string",
+                    editable: false,
+                    sortable: false,
+                    className: "searchTableName"
+                };
+                col['sourceServerName'] = {
+                    label: "Source Server",
+                    cell: "string",
+                    editable: false,
+                    sortable: false,
+                    className: "searchTableName"
+                };
+                col['targetServerName'] = {
+                    label: "Target Server",
+                    cell: "string",
+                    editable: false,
+                    sortable: false,
+                    className: "searchTableName"
+                };
+                col['startTime'] = {
+                    label: "Operation StartTime",
+                    cell: "html",
+                    editable: false,
+                    sortable: false,
+                    formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+                        fromRaw: function(rawValue, model) {
+                            if (rawValue) {
+                                return new Date(rawValue);
+                            } else {
+                                return '-';
+                            }
+                        }
+                    })
+                };
+                col['endTime'] = {
+                    label: "Operation EndTime",
+                    cell: "html",
+                    editable: false,
+                    sortable: false,
+                    formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+                        fromRaw: function(rawValue, model) {
+                            if (rawValue) {
+                                return new Date(rawValue);
+                            } else {
+                                return '-';
+                            }
+                        }
+                    })
+                };
+                col['tools'] = {
+                    label: "Tools",
+                    cell: "html",
+                    editable: false,
+                    sortable: false,
+                    formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+                        fromRaw: function(rawValue, model) {
+                            return '<div class="btn btn-action btn-sm" data-action="audit_detail" data-guid="' + model.get('guid') + '">Detail</div>';
+                        }
+                    })
+                };
+                return this.searchCollection.constructor.getTableCols(col, this.searchCollection);
+            },
+            onClickAuditDetails: function(e) {
+                var that = this;
+                require([
+                    'modules/Modal',
+                    'views/audit/CreateAuditTableLayoutView',
+                ], function(Modal, CreateAuditTableLayoutView) {
+                    $(e.target).attr('disabled', true);
+                    var guid = $(e.target).data("guid"),
+                        model = that.searchCollection.fullCollection.findWhere({ 'guid': guid }),
+                        result = JSON.parse(model.get("resultSummary")),
+                        view = "<table class='table table-bordered table-striped'>" + CommonViewFunction.propertyTable({ scope: that, valueObject: result, attributeDefs: that.attributeDefs }) + "</table>";
+                    var modal = new Modal({
+                        title: model.get("operation") + " Details",
+                        content: view,
+                        contentHtml: true,
+                        okCloses: true,
+                        showFooter: true,
+                    });
+                    modal.open();
+                    modal.on('closeModal', function() {
+                        modal.trigger('cancel');
+                    });
+                    modal.on('hidden.bs.modal', function() {
+                        that.$('.btn-action[data-action="audit_detail"]').attr('disabled', false);
+                    });
+                });
+            },
+        });
+    return ReplicationAuditTableLayoutView;
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/atlas/blob/ab2043a8/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 ecdfc62..f1dddad 100644
--- a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
+++ b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
@@ -44,6 +44,7 @@ define(['require',
                 RTagTableLayoutView: "#r_tagTableLayoutView",
                 RLineageLayoutView: "#r_lineageLayoutView",
                 RAuditTableLayoutView: "#r_auditTableLayoutView",
+                RReplicationAuditTableLayoutView: "#r_replicationAuditTableLayoutView",
                 RProfileLayoutView: "#r_profileLayoutView",
                 RRelationshipLayoutView: "#r_relationshipLayoutView"
             },
@@ -228,6 +229,11 @@ define(['require',
                     }
 
                     if (this.activeEntityDef) {
+                        //to display ReplicationAudit tab
+                        if (collectionJSON && collectionJSON.typeName === "AtlasServer") {
+                            this.$('.replicationTab').show();
+                            this.renderReplicationAuditTableLayoutView(obj);
+                        }
                         // To render Schema check attribute "schemaElementsAttribute"
                         var schemaOptions = this.activeEntityDef.get('options');
                         if (schemaOptions && schemaOptions.hasOwnProperty('schemaElementsAttribute') && schemaOptions.schemaElementsAttribute !== "") {
@@ -489,6 +495,12 @@ define(['require',
                     that.RAuditTableLayoutView.show(new AuditTableLayoutView(obj));
                 });
             },
+            renderReplicationAuditTableLayoutView: function(obj) {
+                var that = this;
+                require(['views/audit/ReplicationAuditTableLayoutView'], function(ReplicationAuditTableLayoutView) {
+                    that.RReplicationAuditTableLayoutView.show(new ReplicationAuditTableLayoutView(obj));
+                });
+            },
             renderProfileLayoutView: function(obj) {
                 var that = this;
                 require(['views/profile/ProfileLayoutView'], function(ProfileLayoutView) {

http://git-wip-us.apache.org/repos/asf/atlas/blob/ab2043a8/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 0707807..5f2eba0 100644
--- a/dashboardv2/public/js/views/search/SearchResultLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchResultLayoutView.js
@@ -69,7 +69,7 @@ define(['require',
                 showPage: "[data-id='showPage']",
                 gotoPage: "[data-id='gotoPage']",
                 gotoPagebtn: "[data-id='gotoPagebtn']",
-                activePage: "[data-id='activePage']",
+                activePage: "[data-id='activePage']"
             },
             templateHelpers: function() {
                 return {