ATLAS-3757 : Classic UI: Add import business metadata feature
diff --git a/dashboardv2/public/css/scss/theme.scss b/dashboardv2/public/css/scss/theme.scss
index 83d6cba..da4c370 100644
--- a/dashboardv2/public/css/scss/theme.scss
+++ b/dashboardv2/public/css/scss/theme.scss
@@ -668,7 +668,7 @@
}
&:hover>.dropdown-menu {
- display: block;
+ display: table;
}
}
diff --git a/dashboardv2/public/js/router/Router.js b/dashboardv2/public/js/router/Router.js
index 3b2090b..68c5fc0 100644
--- a/dashboardv2/public/js/router/Router.js
+++ b/dashboardv2/public/js/router/Router.js
@@ -55,6 +55,7 @@
this.bindCommonEvents();
this.listenTo(this, 'route', this.postRouteExecute, this);
this.searchVent = new Backbone.Wreqr.EventAggregator();
+ this.importVent = new Backbone.Wreqr.EventAggregator();
this.glossaryCollection = new VGlossaryList([], {
comparator: function(item) {
return item.get("name");
@@ -130,14 +131,15 @@
// console.log("Post-Route Change Operations can be performed here !!");
// console.log("Route changed: ", name);
},
- getHeaderOptions: function(Header) {
+ getHeaderOptions: function(Header, options) {
+ var that = this;
return {
view: App.rNHeader,
manualRender: function() {
this.view.currentView.manualRender();
},
render: function() {
- return new Header();
+ return new Header(_.extend({ importVent: that.importVent }, that.preFetchedCollectionLists, that.sharedObj, options));
}
}
},
@@ -238,22 +240,18 @@
], function(Header, GlossaryDetailLayoutView, SideNavLayoutView) {
var paramObj = Utils.getUrlState.getQueryParams();
that.renderViewIfNotExists(that.getHeaderOptions(Header));
+ var options = _.extend({}, that.preFetchedCollectionLists, that.sharedObj, { 'guid': id, 'value': paramObj, importVent: that.importVent })
that.renderViewIfNotExists({
view: App.rSideNav,
manualRender: function() {
- this.view.currentView.RGlossaryLayoutView.currentView.manualRender(_.extend({}, { 'guid': id, 'value': paramObj }));
+ this.view.currentView.RGlossaryLayoutView.currentView.manualRender(options);
this.view.currentView.selectTab();
},
render: function() {
- return new SideNavLayoutView(
- _.extend({}, that.preFetchedCollectionLists, that.sharedObj, { 'guid': id, 'value': paramObj })
- )
+ return new SideNavLayoutView(options)
}
});
- App.rNContent.show(new GlossaryDetailLayoutView(_.extend({
- 'guid': id,
- 'value': paramObj
- }, that.preFetchedCollectionLists, that.sharedObj)));
+ App.rNContent.show(new GlossaryDetailLayoutView(options));
});
}
},
@@ -273,13 +271,14 @@
if (Utils.getUrlState.isTagTab()) {
this.view.currentView.RTagLayoutView.currentView.manualRender();
} else if (Utils.getUrlState.isGlossaryTab()) {
- this.view.currentView.RGlossaryLayoutView.currentView.manualRender(_.extend({ "isTrigger": true }, { "value": paramObj }));
+ this.view.currentView.RGlossaryLayoutView.currentView.manualRender(_.extend({ "isTrigger": true, "value": paramObj }));
}
},
render: function() {
return new SideNavLayoutView(
_.extend({
- 'searchVent': that.searchVent
+ 'searchVent': that.searchVent,
+ 'importVent': that.importVent
}, that.preFetchedCollectionLists, that.sharedObj)
)
}
@@ -296,6 +295,8 @@
} else {
if (App.rNContent.currentView) {
App.rNContent.currentView.destroy();
+ } else {
+ App.rNContent.$el.empty();
}
}
});
diff --git a/dashboardv2/public/js/templates/glossary/ImportGlossaryLayoutView_tmpl.html b/dashboardv2/public/js/templates/import/ImportLayoutView_tmpl.html
similarity index 89%
rename from dashboardv2/public/js/templates/glossary/ImportGlossaryLayoutView_tmpl.html
rename to dashboardv2/public/js/templates/import/ImportLayoutView_tmpl.html
index abf11b7..5bb9ab5 100644
--- a/dashboardv2/public/js/templates/glossary/ImportGlossaryLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/import/ImportLayoutView_tmpl.html
@@ -14,4 +14,4 @@
* See the License for the specific language governing permissions and
* limitations under the License.
-->
-<form action={{importUrl}} id="importGlossary" class="dropzone single-file-center"></form>
\ No newline at end of file
+<form id="importGlossary" class="dropzone single-file-center"></form>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/site/Header.html b/dashboardv2/public/js/templates/site/Header.html
index 1510c19..97e124a 100644
--- a/dashboardv2/public/js/templates/site/Header.html
+++ b/dashboardv2/public/js/templates/site/Header.html
@@ -37,12 +37,36 @@
<table class="header-menu">
<tr>
<td><a class="show-stat" href="javascript:void(0);" title="Statistics"><i class="fa fa-bar-chart"></i></a></td>
- <td><a target="_blank" href="http://atlas.apache.org/"><i class="fa fa-question-circle"></i></a></td>
<td>
<a href="javascript:void(0);" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="user-dropdown"><i class="fa fa-user user-circle "></i><span class="userName"></span></a>
<ul class="dropdown-menu pull-right multi-level">
<li><a href="javascript:void(0)" data-id='administrator'>Administration</a></li>
- <li class="aboutAtlas"><a href="javascript:void(0)">About</a></li>
+ <li class="dropdown-submenu">
+ <a tabindex="-1" href="javascript:void(0)">Bulk Import</span></a>
+ <ul class="dropdown-menu multi-level">
+ <li class="dropdown-submenu">
+ <a tabindex="-1" href="javascript:void(0)">Business Metadata</span></a>
+ <ul class="dropdown-menu">
+ <li><a href="{{businessMetadataImportTempUrl}}">Download Import template</a></li>
+ <li data-id='businessMetadataImport'><a href="javascript:void(0)">Import Business Metadata</a></li>
+ </ul>
+ </li>
+ <li class="dropdown-submenu">
+ <a tabindex="-1" href="javascript:void(0)">Glossary</span></a>
+ <ul class="dropdown-menu">
+ <li><a href="{{glossaryImportTempUrl}}">Download Import template</a></li>
+ <li data-id='glossaryImport'><a href="javascript:void(0)">Import Glossary</a></li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li class="dropdown-submenu">
+ <a tabindex="-1" href="javascript:void(0)">Help</span></a>
+ <ul class="dropdown-menu">
+ <li><a target="_blank" href="http://atlas.apache.org/">Documentation</a></li>
+ <li class="aboutAtlas"><a href="javascript:void(0)">About</a></li>
+ </ul>
+ </li>
<li role="separator" class="divider"></li>
<li><a data-id="uiSwitch" href="javascript:void(0)">Switch to New</a></li>
<li>
diff --git a/dashboardv2/public/js/utils/UrlLinks.js b/dashboardv2/public/js/utils/UrlLinks.js
index 3bfef85..6d3c079 100644
--- a/dashboardv2/public/js/utils/UrlLinks.js
+++ b/dashboardv2/public/js/utils/UrlLinks.js
@@ -202,6 +202,12 @@
glossaryImportUrl: function() {
return this.glossaryApiUrl() + '/import';
},
+ businessMetadataImportTempUrl: function() {
+ return this.entitiesApiUrl() + '/businessmetadata/import/template';
+ },
+ businessMetadataImportUrl: function() {
+ return this.entitiesApiUrl() + '/businessmetadata/import';
+ },
categoryApiUrl: function(options) {
var guid = options && options.guid,
list = options && options.list,
diff --git a/dashboardv2/public/js/views/glossary/GlossaryLayoutView.js b/dashboardv2/public/js/views/glossary/GlossaryLayoutView.js
index 030a939..c2ad03f 100644
--- a/dashboardv2/public/js/views/glossary/GlossaryLayoutView.js
+++ b/dashboardv2/public/js/views/glossary/GlossaryLayoutView.js
@@ -97,7 +97,7 @@
* @constructs
*/
initialize: function(options) {
- _.extend(this, _.pick(options, 'associatedTerms', 'guid', 'value', 'glossaryCollection', 'glossary', 'isAssignTermView', 'isAssignCategoryView', 'isAssignEntityView', 'isAssignAttributeRelationView'));
+ _.extend(this, _.pick(options, 'associatedTerms', 'guid', 'value', 'glossaryCollection', 'glossary', 'isAssignTermView', 'isAssignCategoryView', 'isAssignEntityView', 'isAssignAttributeRelationView', 'importVent'));
this.viewType = "term";
this.isAssignView = this.isAssignTermView || this.isAssignCategoryView || this.isAssignEntityView || this.isAssignAttributeRelationView;
this.bindEvents();
@@ -142,6 +142,9 @@
that[$(this).find('a').data('fn')](e)
});
}
+ this.importVent.on("Import:Glossary:Update", function(options) {
+ that.getGlossary();
+ });
},
onRender: function() {
this.changeLoaderState(true);
@@ -772,12 +775,13 @@
onClickImportGlossary: function() {
var that = this;
require([
- 'views/glossary/ImportGlossaryLayoutView'
- ], function(ImportGlossaryLayoutView) {
- var view = new ImportGlossaryLayoutView({
+ 'views/import/ImportLayoutView'
+ ], function(ImportLayoutView) {
+ var view = new ImportLayoutView({
callback: function() {
that.getGlossary();
- }
+ },
+ isGlossary: true
});
});
}
diff --git a/dashboardv2/public/js/views/glossary/ImportGlossaryLayoutView.js b/dashboardv2/public/js/views/import/ImportLayoutView.js
similarity index 70%
rename from dashboardv2/public/js/views/glossary/ImportGlossaryLayoutView.js
rename to dashboardv2/public/js/views/import/ImportLayoutView.js
index 23b0ef7..81e4d33 100644
--- a/dashboardv2/public/js/views/glossary/ImportGlossaryLayoutView.js
+++ b/dashboardv2/public/js/views/import/ImportLayoutView.js
@@ -19,25 +19,19 @@
define([
"require",
"backbone",
- "hbs!tmpl/glossary/ImportGlossaryLayoutView_tmpl",
+ "hbs!tmpl/import/ImportLayoutView_tmpl",
"modules/Modal",
'utils/CommonViewFunction',
"utils/Utils",
"utils/UrlLinks",
"dropzone"
-], function(require, Backbone, ImportGlossaryLayoutViewTmpl, Modal, CommonViewFunction, Utils, UrlLinks, dropzone) {
- var ImportGlossaryLayoutView = Backbone.Marionette.LayoutView.extend(
- /** @lends ImportGlossaryLayoutView */
+], function(require, Backbone, ImportLayoutViewTmpl, Modal, CommonViewFunction, Utils, UrlLinks, dropzone) {
+ var ImportLayoutView = Backbone.Marionette.LayoutView.extend(
+ /** @lends ImportLayoutView */
{
- _viewName: "ImportGlossaryLayoutView",
+ _viewName: "ImportLayoutView",
- template: ImportGlossaryLayoutViewTmpl,
-
- templateHelpers: function() {
- return {
- importUrl: UrlLinks.glossaryImportUrl()
- };
- },
+ template: ImportLayoutViewTmpl,
/** Layout sub regions */
regions: {},
@@ -50,14 +44,14 @@
return events;
},
/**
- * intialize a new ImportGlossaryLayoutView Layout
+ * intialize a new ImportLayoutView Layout
* @constructs
*/
initialize: function(options) {
- _.extend(this, _.pick(options, "callback"));
+ _.extend(this, _.pick(options, "callback", "isGlossary"));
var that = this;
this.modal = new Modal({
- title: "Import Glossary",
+ title: this.isGlossary ? "Import Glossary" : "Import Business Metadata",
content: this,
cancelText: "Cancel",
okText: "upload",
@@ -88,7 +82,7 @@
var headers = {};
headers[CommonViewFunction.restCsrfCustomHeader] = '""';
this.$("#importGlossary").dropzone({
- url: UrlLinks.glossaryImportUrl(),
+ url: that.isGlossary ? UrlLinks.glossaryImportUrl() : UrlLinks.businessMetadataImportUrl(),
clickable: true,
acceptedFiles: ".csv,.xls,.xlsx",
autoProcessQueue: false,
@@ -107,12 +101,21 @@
this.removeAllFiles();
this.addFile(file);
},
- success: function(file, response) {
- that.modal.trigger("cancel");
- Utils.notifySuccess({
- content: "File: " + file.name + " added successfully"
- });
- that.callback();
+ success: function(file, response, responseObj) {
+ var success = true;
+ if (response.failedImportInfoList && response.failedImportInfoList.length) {
+ success = false;
+ Utils.defaultErrorHandler(null, file.xhr, { defaultErrorMessage: response.failedImportInfoList[0].remarks });
+ }
+ if (success) {
+ that.modal.trigger("cancel");
+ Utils.notifySuccess({
+ content: "File: " + file.name + " imported successfully"
+ });
+ }
+ if (that.callback && ((response.successImportInfoList && response.successImportInfoList.length > 0) || success)) {
+ that.callback();
+ }
},
error: function(file, response, responseObj) {
Utils.defaultErrorHandler(null, responseObj, { defaultErrorMessage: (response.errorMessage) || response });
@@ -124,5 +127,5 @@
}
}
);
- return ImportGlossaryLayoutView;
+ return ImportLayoutView;
});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/site/Header.js b/dashboardv2/public/js/views/site/Header.js
index 48279e4..b77ee1f 100644
--- a/dashboardv2/public/js/views/site/Header.js
+++ b/dashboardv2/public/js/views/site/Header.js
@@ -29,6 +29,12 @@
var Header = Marionette.LayoutView.extend({
template: tmpl,
regions: {},
+ templateHelpers: function() {
+ return {
+ glossaryImportTempUrl: UrlLinks.glossaryImportTempUrl(),
+ businessMetadataImportTempUrl: UrlLinks.businessMetadataImportTempUrl()
+ };
+ },
ui: {
backButton: "[data-id='backButton']",
menuHamburger: "[data-id='menuHamburger']",
@@ -36,7 +42,9 @@
clearGlobalSearch: "[data-id='clearGlobalSearch']",
signOut: "[data-id='signOut']",
administrator: "[data-id='administrator']",
- uiSwitch: "[data-id='uiSwitch']"
+ uiSwitch: "[data-id='uiSwitch']",
+ glossaryImport: "[data-id='glossaryImport']",
+ businessMetadataImport: "[data-id='businessMetadataImport']"
},
events: function() {
var events = {};
@@ -76,15 +84,22 @@
updateTabState: true
});
};
+ events['click ' + this.ui.glossaryImport] = function() {
+ this.onClickImport(true);
+ };
+ events['click ' + this.ui.businessMetadataImport] = function() {
+ this.onClickImport()
+ };
return events;
},
initialize: function(options) {
this.bindEvent();
+ this.options = options;
},
setSearchBoxWidth: function(options) {
var atlasHeaderWidth = this.$el.find(".atlas-header").width(),
- minusWidth = (Utils.getUrlState.isDetailPage() || Utils.getUrlState.isBSDetail()) ? 413 : 263;
+ minusWidth = (Utils.getUrlState.isDetailPage() || Utils.getUrlState.isBSDetail()) ? 360 : 210;
if (options && options.updateWidth) {
atlasHeaderWidth = options.updateWidth(atlasHeaderWidth);
}
@@ -276,6 +291,23 @@
}
}
};
+ },
+ onClickImport: function(isGlossary) {
+ var that = this;
+ require([
+ 'views/import/ImportLayoutView'
+ ], function(ImportLayoutView) {
+ var view = new ImportLayoutView({
+ callback: function() {
+ if (isGlossary) {
+ that.options.importVent.trigger("Import:Glossary:Update");
+ } else {
+ that.options.importVent.trigger("Import:BM:Update");
+ }
+ },
+ isGlossary: isGlossary
+ });
+ });
}
});
return Header;
diff --git a/dashboardv3/public/css/scss/theme.scss b/dashboardv3/public/css/scss/theme.scss
index 84552cb..c126809 100644
--- a/dashboardv3/public/css/scss/theme.scss
+++ b/dashboardv3/public/css/scss/theme.scss
@@ -780,7 +780,7 @@
}
&:hover>.dropdown-menu {
- display: block;
+ display: table;
}
}
diff --git a/dashboardv3/public/js/templates/site/Header.html b/dashboardv3/public/js/templates/site/Header.html
index ef670d6..6d5e6ef 100644
--- a/dashboardv3/public/js/templates/site/Header.html
+++ b/dashboardv3/public/js/templates/site/Header.html
@@ -44,7 +44,7 @@
<ul class="dropdown-menu pull-right multi-level" role="menu" aria-labelledby="dropdownMenu">
<li><a href="javascript:void(0)" data-id='administrator'>Administration</a></li>
<li class="dropdown-submenu">
- <a tabindex="-1" href="javascript:void(0)"> Help </span></a>
+ <a tabindex="-1" href="javascript:void(0)">Help</span></a>
<ul class="dropdown-menu">
<li><a target="_blank" href="http://atlas.apache.org/">Documentation</a></li>
<li class="aboutAtlas"><a href="javascript:void(0)">About</a></li>
diff --git a/dashboardv3/public/js/views/import/ImportLayoutView.js b/dashboardv3/public/js/views/import/ImportLayoutView.js
index d04847e..81e4d33 100644
--- a/dashboardv3/public/js/views/import/ImportLayoutView.js
+++ b/dashboardv3/public/js/views/import/ImportLayoutView.js
@@ -101,18 +101,19 @@
this.removeAllFiles();
this.addFile(file);
},
- success: function(file, response) {
- if (response.successImportInfoList.length && response.failedImportInfoList.length === 0) {
+ success: function(file, response, responseObj) {
+ var success = true;
+ if (response.failedImportInfoList && response.failedImportInfoList.length) {
+ success = false;
+ Utils.defaultErrorHandler(null, file.xhr, { defaultErrorMessage: response.failedImportInfoList[0].remarks });
+ }
+ if (success) {
that.modal.trigger("cancel");
Utils.notifySuccess({
content: "File: " + file.name + " imported successfully"
});
- } else if (response.failedImportInfoList.length) {
- Utils.notifyError({
- content: response.failedImportInfoList[0].remarks
- });
}
- if (that.callback) {
+ if (that.callback && ((response.successImportInfoList && response.successImportInfoList.length > 0) || success)) {
that.callback();
}
},