ATLAS-3748 : UI: Add new UI feature into Classic UI
diff --git a/dashboardv2/public/css/scss/business-metadata.scss b/dashboardv2/public/css/scss/business-metadata.scss
new file mode 100644
index 0000000..6502fb5
--- /dev/null
+++ b/dashboardv2/public/css/scss/business-metadata.scss
@@ -0,0 +1,199 @@
+// 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.
+
+
+/* business-metadata */
+.business-metadata-tree-parent {
+ padding: 0px;
+
+ >li:first-child {
+ font-weight: 600;
+ }
+
+ .business-metadata-tree-child {
+ &.entity-detail-table table {
+ td {
+ &:nth-child(1) {
+ width: 35%;
+ }
+
+ word-break: break-word;
+ }
+ }
+
+ padding-left: 5px;
+ margin-top: 10px;
+ font-weight: 100;
+ }
+}
+
+.business-metadata-options.dropdown {
+ .dropdown-menu {
+ min-width: 100px;
+
+ .dropdown-item {
+ display: block;
+ width: 100%;
+ padding: .25rem 1.5rem;
+ clear: both;
+ font-weight: 400;
+ color: $color_jungle_green_approx;
+ text-align: inherit;
+ white-space: nowrap;
+ background-color: transparent;
+ border: 0;
+ }
+ }
+}
+
+.business-metadata-options.dropdown.open {
+ .btn-action {
+ background-color: $color_jungle_green_approx;
+ border: 1px solid $color_jungle_green_approx;
+ color: #fff !important;
+ }
+}
+
+.business-metadata-details,
+.admin-details {
+ .expandable .attr-details {
+ max-height: 300px;
+ overflow: auto;
+ margin-left: 30px;
+ width: calc(100% - 30px);
+ }
+
+ .admin-type-dropdown {
+ width: 100px;
+ }
+
+ .expandable .admin-attr-details {
+ max-height: 100px;
+ margin-left: 20px;
+ width: calc(100% - 27px);
+ }
+}
+
+.tab-pane {
+ .business-metadata-attr-page {
+ position: absolute;
+ top: 62px;
+ left: 0px;
+ padding: 20px;
+ background-color: $white;
+ width: 100%;
+ height: inherit;
+ }
+}
+
+.business-metadata-attr-page {
+ .form-horizontal {
+ padding: 10px 22px;
+ // border: 1px solid #DEDEDE;
+
+ .control-label-sm {
+ padding-top: 3px;
+ }
+
+ .control-label-sm-pl {
+ @extend .control-label-sm;
+ padding-left: 10px;
+ }
+
+ .control-label-sm-pr {
+ @extend .control-label-sm;
+ padding-right: 10px;
+ }
+
+ .business-metadata-attr {
+ border: 1px solid #DEDEDE;
+ padding: 10px 20px
+ }
+ }
+}
+
+.business-metadata-attr-fontLoader {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ display: none;
+}
+
+.business-metadata-attr-tableOverlay {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ background: #808080;
+ z-index: 99;
+ display: none;
+ opacity: 0.2;
+}
+
+.business-metadata-details {
+ .backgrid {
+ td.expandable-content {
+ max-width: none;
+ background: #f8f8f8;
+
+ div {
+
+ table {
+ width: 100%;
+ }
+ }
+ }
+
+ tbody>tr:last-child>td {
+ border-bottom: none;
+ }
+ }
+}
+
+.business-metadata-attr-page {
+ .modal-footer {
+ text-align: center;
+ }
+}
+
+.remove-from-list {
+ .select2-results__option[aria-selected=true] {
+ display: none;
+ }
+}
+
+.business-metadata-detail-attr {
+ margin-bottom: 0px;
+ box-shadow: none;
+
+ .panel-heading {
+ color: #686868 !important;
+ font-size: 13px;
+ padding: 0;
+
+ .panel-title {
+ font-size: 14px;
+
+ a:hover {
+ color: #686868 !important;
+ opacity: 1 !important;
+ }
+ }
+ }
+
+ .btn-group>button {
+ color: #686868 !important;
+ }
+}
\ No newline at end of file
diff --git a/dashboardv2/public/css/scss/common.scss b/dashboardv2/public/css/scss/common.scss
index 718ac95..0844124 100644
--- a/dashboardv2/public/css/scss/common.scss
+++ b/dashboardv2/public/css/scss/common.scss
@@ -274,6 +274,15 @@
float: left;
}
+.errorValidate {
+ border-color: red !important;
+}
+
+.errorValidate+span .select2-selection {
+ border-color: red !important;
+
+}
+
.button-loader {
position: relative;
padding-left: 22px !important;
diff --git a/dashboardv2/public/css/scss/override.scss b/dashboardv2/public/css/scss/override.scss
index b6c42f6..8946fdd 100644
--- a/dashboardv2/public/css/scss/override.scss
+++ b/dashboardv2/public/css/scss/override.scss
@@ -72,6 +72,17 @@
}
}
+.modal-full-screen {
+ width: 80%;
+ height: 80vh;
+
+ .modal-content {
+ height: inherit;
+ width: 100%;
+ }
+
+}
+
.switch.pull-left {
margin-right: 8px;
}
@@ -80,58 +91,6 @@
border-radius: 10px;
}
-.table-quickMenu {
- border: thin $lightGrey solid;
- border-collapse: separate;
- border-radius: 6px;
- box-shadow: 0px 0px 4px #d8d8d8;
- overflow: scroll !important;
- max-height: 500px;
- width: 100%;
-
- .resizeHandler {
- &.grid-draggable {
- background-color: $color_jungle_green_approx !important;
- }
-
- &:hover {
- border-left: 1px solid #d2d2d2;
- }
- }
-
- >thead>tr>th {
- border-width: thin;
- border-color: $color_jungle_green_approx;
- border-bottom-style: solid;
- box-shadow: none;
- padding: 20px 15px;
- background-color: transparent;
- text-align: left;
- font-weight: 800;
- border-top: 0;
- font-size: 14px;
- letter-spacing: 0.25px;
- color: rgba(52, 52, 52, 1);
- }
-
- >tbody>tr>td {
- border-color: $color_gallery_approx;
- color: #333333;
- font-weight: 100;
- padding: 10px 15px;
- }
-}
-
-td {
-
- div.scroll-y,
- pre.scroll-y {
- max-height: 200px;
- overflow-y: auto;
- word-break: break-word;
- }
-}
-
.select2-container {
width: 100% !important;
@@ -262,7 +221,7 @@
}
.popover {
- z-index: 99;
+ z-index: 1000;
}
.popover-content {
@@ -284,6 +243,7 @@
.tab-content>.tab-pane.active {
overflow-x: hidden;
+ overflow: initial;
}
.advancedInfo {
@@ -404,6 +364,10 @@
}
div.columnmanager-dropdown-container {
+ .columnmanager-dropdown-item {
+ padding: 2px 13px;
+ }
+
&.open {
overflow: auto;
width: auto;
@@ -496,4 +460,34 @@
.w30 {
width: 30% !important;
+}
+
+.query-builder .error-container {
+ cursor: pointer;
+}
+
+.renderable {
+ .glyphicon {
+ color: $color_jungle_green_approx;
+ font-size: large;
+ font-weight: bold;
+ }
+}
+
+.backgrid-internal-table {
+
+ th,
+ td {
+ display: table-cell;
+ }
+}
+
+.table-hover>tbody>tr:hover {
+ background-color: #fafafa;
+}
+
+.input-group {
+ .form-control {
+ z-index: 1;
+ }
}
\ No newline at end of file
diff --git a/dashboardv2/public/css/scss/search.scss b/dashboardv2/public/css/scss/search.scss
index fdb4d69..f10d962 100644
--- a/dashboardv2/public/css/scss/search.scss
+++ b/dashboardv2/public/css/scss/search.scss
@@ -283,4 +283,56 @@
}
}
}
+}
+
+.attributeResultContainer {
+ &.overlay {
+ z-index: 3;
+ }
+
+ .attribute-filter-container {
+ position: absolute;
+ z-index: 3;
+ left: 21px;
+ width: 75%;
+ right: 0;
+ // display: none;
+ background: $white;
+ box-shadow: 0px 13px 34px -13px grey;
+ padding: 15px;
+ transition: all ease 0.3s;
+
+ &.no-attr {
+ .filter-box {
+ display: inline-block;
+ padding: 0px 15px;
+ }
+ }
+
+ .filter-box {
+ padding: 5px;
+ }
+
+ .entity-detail-table-toggle {
+ display: inline-block;
+ }
+
+ .pretty.p-switch.p-fill input:checked~.state.p-primary:before {
+ background-color: #38bb9b !important;
+ }
+
+ .pretty.p-switch input:checked~.state.p-primary:before {
+ border-color: #38bb9b;
+ }
+
+ .panel {
+ border: none;
+ }
+
+ .attribute-result-footer,
+ .attribute-edit-footer {
+ text-align: right;
+ }
+ }
+
}
\ No newline at end of file
diff --git a/dashboardv2/public/css/scss/style.scss b/dashboardv2/public/css/scss/style.scss
index 4ee7cf9..9f4482c 100644
--- a/dashboardv2/public/css/scss/style.scss
+++ b/dashboardv2/public/css/scss/style.scss
@@ -34,5 +34,6 @@
@import "profile-table.scss";
@import "glossary.scss";
@import "wizard.scss";
+@import "business-metadata.scss";
@import "stats.scss";
@import "override.scss";
\ No newline at end of file
diff --git a/dashboardv2/public/css/scss/tab.scss b/dashboardv2/public/css/scss/tab.scss
index d864f6e..1da54e0 100644
--- a/dashboardv2/public/css/scss/tab.scss
+++ b/dashboardv2/public/css/scss/tab.scss
@@ -68,7 +68,7 @@
overflow: hidden;
&.active {
- padding: 25px;
+ padding: 15px 20px;
opacity: 1;
height: auto;
overflow: auto;
@@ -136,10 +136,6 @@
}
}
-.tab-pane {
- padding: 25px;
-}
-
.atlast-tabbable {
margin: 25px 0;
@@ -185,6 +181,7 @@
&.active {
>a {
color: $color_jungle_green_approx;
+ // background: $color_white_lilac_approx;
}
}
diff --git a/dashboardv2/public/css/scss/table.scss b/dashboardv2/public/css/scss/table.scss
index 0d32351..2ee30a2 100644
--- a/dashboardv2/public/css/scss/table.scss
+++ b/dashboardv2/public/css/scss/table.scss
@@ -36,12 +36,6 @@
}
}
-.table-action-btn {
- position: absolute;
- right: 0px;
- top: -5px;
-}
-
.entity-detail-table,
.relationship-detail-table {
position: relative;
@@ -56,7 +50,7 @@
.entity-detail-table-toggle {
position: absolute;
right: 0;
- top: 18px;
+ top: 7px;
}
table {
@@ -73,11 +67,6 @@
white-space: normal;
}
- th.renderable.html-cell,
- td.renderable.html-cell {
- min-width: 250px;
- }
-
.select-all-header-cell,
.select-row-cell {
width: 42px;
@@ -189,26 +178,40 @@
}
}
- >thead>tr>th {
- border-width: thin;
- border-color: $color_jungle_green_approx;
- border-bottom-style: solid;
- box-shadow: none;
- padding: 12px 15px !important;
- background-color: transparent;
- text-align: left;
- font-weight: 800;
- border-top: 0;
- font-size: 14px;
- letter-spacing: 0.25px;
- color: rgba(52, 52, 52, 1);
+ >thead>tr {
+ background: #eeeeee;
+
+ &>th {
+ border-width: thin;
+ // border-color: $color_jungle_green_approx;
+ border-bottom-style: solid;
+ box-shadow: none;
+ padding: 6px 15px !important;
+ background-color: transparent;
+ text-align: left;
+ font-weight: 800;
+ border-top: 0;
+ font-size: 14px;
+ letter-spacing: 0.25px;
+ color: #6a6a6a;
+
+ &.no-capitalize {
+ text-transform: none !important;
+ }
+ }
+
+ >td {
+ border-color: $color_gallery_approx;
+ color: #333333;
+ font-weight: 100;
+ padding: 9px 15px;
+ }
}
>tbody>tr>td {
- border-color: $color_gallery_approx;
- color: #333333;
- font-weight: 100;
- padding: 9px 15px;
+ &.select-row-cell {
+ text-align: center;
+ }
}
}
@@ -246,4 +249,14 @@
float: left;
}
}
+}
+
+.auditStatusContainer {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+}
+
+.auditStatusContainer>div {
+ flex-grow: 1;
}
\ No newline at end of file
diff --git a/dashboardv2/public/css/scss/theme.scss b/dashboardv2/public/css/scss/theme.scss
index a4fc184..83d6cba 100644
--- a/dashboardv2/public/css/scss/theme.scss
+++ b/dashboardv2/public/css/scss/theme.scss
@@ -83,6 +83,21 @@
}
}
+#new-page-wrapper {
+ height: calc(100vh - 63px);
+ overflow: auto;
+ padding-top: 15px !important;
+ padding-bottom: 10px !important;
+
+ &>div {
+ height: 100%;
+ }
+}
+
+.full-parent-width {
+ height: 100%;
+}
+
.sidebar-brand {
padding-left: 6px !important;
@@ -136,8 +151,7 @@
}
.page-title {
- background-color: $color_white_lilac_approx;
- padding: 15px 15px 0px 15px;
+ padding: 0px 15px 0px 15px;
.title {
padding-top: 0;
@@ -296,12 +310,9 @@
}
}
-@media (min-width: 768px) {
- .col-sm-custom {
- //width: 92%;
- margin: 25px 25px 0px;
- position: relative;
- }
+.col-sm-custom {
+ margin: 15px 25px 0px;
+ position: relative;
}
.no-padding {
@@ -524,6 +535,17 @@
}
}
+.tooltip-inner {
+ max-width: none;
+ color: #2c2c2c;
+ background-color: #f9f9f9;
+ box-shadow: 0px 0px 3px 0px #8080806b;
+}
+
+.tooltip.bottom .tooltip-arrow {
+ border-bottom-color: #000;
+}
+
td.searchTableName:hover {
.isIncomplete {
&.show.search-result-page {
@@ -611,6 +633,62 @@
}
}
+
+.dropdown-menu.multi-level {
+ .dropdown-submenu {
+ position: relative;
+
+ &>a:after {
+ display: none;
+ content: " ";
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+ border-width: 5px 5px 5px 0px;
+ border-right-color: #ccc;
+ position: absolute;
+ left: 8px;
+ top: calc(50% - 5px);
+ }
+
+ &>a:hover:after {
+ display: block;
+ }
+
+ &>.dropdown-menu {
+ top: 0;
+ left: -100%;
+ width: 100%;
+ margin-top: -6px;
+ margin-left: -1px;
+ -webkit-border-radius: 0 6px 6px 6px;
+ -moz-border-radius: 0 6px 6px;
+ border-radius: 0 6px 6px 6px;
+ }
+
+ &:hover>.dropdown-menu {
+ display: block;
+ }
+
+ }
+}
+
+.select2-results__option {
+ &.select2-results__option--highlighted {
+ .option-title-light {
+ color: #eaeaea;
+ }
+ }
+
+ .option-title-light {
+ font-size: 12px;
+ color: #a4a4a4;
+ }
+
+
+}
+
.dropzone {
border-radius: 10px;
border: 2px dashed $color_havelock_blue_approx;
diff --git a/dashboardv2/public/index.html.tpl b/dashboardv2/public/index.html.tpl
index ba1ccf0..2cb0012 100644
--- a/dashboardv2/public/index.html.tpl
+++ b/dashboardv2/public/index.html.tpl
@@ -78,7 +78,7 @@
<div id="sideNav-wrapper"></div>
</div>
<div id="page-content-wrapper" class="page-content-wrapper">
- <header id="new-header" class="clearfix"></header>
+ <div id="new-header" class="clearfix"></div>
<div id="new-page-wrapper">
<div>
<div class="initialLoading"></div>
diff --git a/dashboardv2/public/js/collection/BaseCollection.js b/dashboardv2/public/js/collection/BaseCollection.js
index 23bd89a..30f5b76 100644
--- a/dashboardv2/public/js/collection/BaseCollection.js
+++ b/dashboardv2/public/js/collection/BaseCollection.js
@@ -130,6 +130,9 @@
nonCrudOperation: function(url, requestMethod, options) {
var that = this;
options['beforeSend'] = CommonViewFunction.addRestCsrfCustomHeader;
+ if (options.data && typeof options.data === "object") {
+ options.data = JSON.stringify(options.data);
+ }
return Backbone.sync.call(this, null, this, _.extend({
url: url,
type: requestMethod
diff --git a/dashboardv2/public/js/collection/VEntityList.js b/dashboardv2/public/js/collection/VEntityList.js
index e4e2ba3..645bc0c 100644
--- a/dashboardv2/public/js/collection/VEntityList.js
+++ b/dashboardv2/public/js/collection/VEntityList.js
@@ -54,6 +54,14 @@
} catch (e) {
console.log(e);
}
+ },
+ getAdminData: function(options) {
+ var url = UrlLinks.adminApiUrl();
+ options = _.extend({
+ contentType: 'application/json',
+ dataType: 'json'
+ }, options);
+ return this.constructor.nonCrudOperation.call(this, url, 'POST', options);
}
},
//Static Class Members
diff --git a/dashboardv2/public/js/main.js b/dashboardv2/public/js/main.js
index 9361a7b..cc1b69c 100644
--- a/dashboardv2/public/js/main.js
+++ b/dashboardv2/public/js/main.js
@@ -44,6 +44,7 @@
*/
'waitSeconds': 0,
+
'shim': {
'backbone': {
'deps': ['underscore', 'jquery'],
@@ -203,25 +204,35 @@
'select2'
], function(App, Router, Helper, CommonViewFunction, Globals, UrlLinks, VEntityList, VTagList, Enums) {
var that = this;
- this.asyncFetchCounter = 6 + (Enums.addOnEntities.length + 1);
+ this.asyncFetchCounter = 7 + (Enums.addOnEntities.length + 1);
+ // entity
this.entityDefCollection = new VEntityList();
this.entityDefCollection.url = UrlLinks.entitiesDefApiUrl();
+ // typeHeaders
this.typeHeaders = new VTagList();
this.typeHeaders.url = UrlLinks.typesApiUrl();
+ // enum
this.enumDefCollection = new VTagList();
this.enumDefCollection.url = UrlLinks.enumDefApiUrl();
this.enumDefCollection.modelAttrName = "enumDefs";
+ // classfication
this.classificationDefCollection = new VTagList();
+ // metric
this.metricCollection = new VTagList();
this.metricCollection.url = UrlLinks.metricsApiUrl();
this.metricCollection.modelAttrName = "data";
+ // businessMetadata
+ this.businessMetadataDefCollection = new VEntityList();
+ this.businessMetadataDefCollection.url = UrlLinks.businessMetadataDefApiUrl();
+ this.businessMetadataDefCollection.modelAttrName = "businessMetadataDefs";
App.appRouter = new Router({
entityDefCollection: this.entityDefCollection,
typeHeaders: this.typeHeaders,
enumDefCollection: this.enumDefCollection,
classificationDefCollection: this.classificationDefCollection,
- metricCollection: this.metricCollection
+ metricCollection: this.metricCollection,
+ businessMetadataDefCollection: this.businessMetadataDefCollection
});
var startApp = function() {
@@ -309,6 +320,17 @@
}
});
+ this.businessMetadataDefCollection.fetch({
+ complete: function() {
+ that.businessMetadataDefCollection.fullCollection.comparator = function(model) {
+ return model.get('name').toLowerCase();
+ };
+ that.businessMetadataDefCollection.fullCollection.sort({ silent: true });
+ --that.asyncFetchCounter;
+ startApp();
+ }
+ });
+
Enums.addOnEntities.forEach(function(addOnEntity) {
CommonViewFunction.fetchRootEntityAttributes({
url: UrlLinks.rootEntityDefUrl(addOnEntity),
@@ -322,7 +344,7 @@
CommonViewFunction.fetchRootClassificationAttributes({
url: UrlLinks.rootClassificationDefUrl(Enums.addOnClassification[0]),
- classification: Enums.addOnClassification[0],
+ classification: Enums.addOnClassification,
callback: function() {
--that.asyncFetchCounter;
startApp();
diff --git a/dashboardv2/public/js/models/BaseModel.js b/dashboardv2/public/js/models/BaseModel.js
index 654b5f2..eaeb534 100644
--- a/dashboardv2/public/js/models/BaseModel.js
+++ b/dashboardv2/public/js/models/BaseModel.js
@@ -57,6 +57,9 @@
nonCrudOperation: function(url, requestMethod, options) {
var that = this;
options['beforeSend'] = CommonViewFunction.addRestCsrfCustomHeader;
+ if (options.data && typeof options.data === "object") {
+ options.data = JSON.stringify(options.data);
+ }
return Backbone.sync.call(this, null, this, _.extend({
url: url,
type: requestMethod
diff --git a/dashboardv2/public/js/models/VEntity.js b/dashboardv2/public/js/models/VEntity.js
index b798a6b..5c50386 100644
--- a/dashboardv2/public/js/models/VEntity.js
+++ b/dashboardv2/public/js/models/VEntity.js
@@ -95,6 +95,26 @@
dataType: 'json'
}, options);
return this.constructor.nonCrudOperation.call(this, url, "POST", options);
+ },
+ saveBusinessMetadata: function(options) {
+ var url = UrlLinks.businessMetadataDefApiUrl();
+ options = _.extend({
+ contentType: 'application/json',
+ dataType: 'json'
+ }, options);
+ return this.constructor.nonCrudOperation.call(this, url, '', options);
+ },
+ deleteBusinessMetadata: function(options) {
+ var url = UrlLinks.businessMetadataDefApiUrl(options.typeName);
+ return this.constructor.nonCrudOperation.call(this, url, 'DELETE', options);
+ },
+ saveBusinessMetadataEntity: function(guid, options) {
+ var url = UrlLinks.entitiesBusinessMetadataApiUrl(guid);
+ options = _.extend({
+ contentType: 'application/json',
+ dataType: 'json'
+ }, options);
+ return this.constructor.nonCrudOperation.call(this, url, 'POST', options);
}
}, {});
return VEntity;
diff --git a/dashboardv2/public/js/modules/Helpers.js b/dashboardv2/public/js/modules/Helpers.js
index 2f36a0d..7ef5f25 100644
--- a/dashboardv2/public/js/modules/Helpers.js
+++ b/dashboardv2/public/js/modules/Helpers.js
@@ -89,6 +89,12 @@
case '>=':
return (v1 >= v2) ? options.fn(this) : options.inverse(this);
break;
+ case 'isEmpty':
+ return (_.isEmpty(v1)) ? options.fn(this) : options.inverse(this);
+ break;
+ case 'has':
+ return (_.has(v1, v2)) ? options.fn(this) : options.inverse(this);
+ break;
default:
return options.inverse(this);
break;
diff --git a/dashboardv2/public/js/router/Router.js b/dashboardv2/public/js/router/Router.js
index 74b99b8..3b2090b 100644
--- a/dashboardv2/public/js/router/Router.js
+++ b/dashboardv2/public/js/router/Router.js
@@ -30,20 +30,27 @@
var AppRouter = Backbone.Router.extend({
routes: {
// Define some URL routes
- '': 'defaultAction',
- '!/': 'tagAttributePageLoad',
- '!/tag/tagAttribute/(*name)': 'tagAttributePageLoad',
- '!/search/searchResult': 'searchResult',
- '!/detailPage/:id': 'detailPage',
- '!/tag': 'commonAction',
- '!/search': 'commonAction',
- '!/glossary': 'commonAction',
- '!/glossary/:id': 'glossaryDetailPage',
+ "": "defaultAction",
+ "!/": "tagAttributePageLoad",
+ // Search
+ "!/search": "commonAction",
+ "!/search/searchResult": "searchResult",
+ // Tag
+ "!/tag": "commonAction",
+ "!/tag/tagAttribute/(*name)": "tagAttributePageLoad",
+ // Glossary
+ "!/glossary": "commonAction",
+ "!/glossary/:id": "glossaryDetailPage",
+ // Details
+ "!/detailPage/:id": "detailPage",
+ //Administrator page
+ '!/administrator': 'administrator',
+ '!/administrator/businessMetadata/:id': 'businessMetadataDetailPage',
// Default
'*actions': 'defaultAction'
},
initialize: function(options) {
- _.extend(this, _.pick(options, 'entityDefCollection', 'typeHeaders', 'enumDefCollection', 'classificationDefCollection', 'metricCollection'));
+ _.extend(this, _.pick(options, 'entityDefCollection', 'typeHeaders', 'enumDefCollection', 'classificationDefCollection', 'metricCollection', 'businessMetadataDefCollection'));
this.showRegions();
this.bindCommonEvents();
this.listenTo(this, 'route', this.postRouteExecute, this);
@@ -59,7 +66,8 @@
'enumDefCollection': this.enumDefCollection,
'classificationDefCollection': this.classificationDefCollection,
'glossaryCollection': this.glossaryCollection,
- 'metricCollection': this.metricCollection
+ 'metricCollection': this.metricCollection,
+ 'businessMetadataDefCollection': this.businessMetadataDefCollection
}
this.sharedObj = {
searchTableColumns: {},
@@ -292,6 +300,69 @@
}
});
},
+ administrator: function() {
+ var that = this;
+ require(["views/site/Header", "views/site/SideNavLayoutView", 'views/administrator/AdministratorLayoutView'], function(Header, SideNavLayoutView, AdministratorLayoutView) {
+ var value = Utils.getUrlState.getQueryParams(),
+ paramObj = Utils.getUrlState.getQueryParams();
+ that.renderViewIfNotExists(that.getHeaderOptions(Header));
+ that.renderViewIfNotExists({
+ view: App.rSideNav,
+ manualRender: function() {
+ this.view.currentView.selectTab();
+ 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 }));
+ }
+ },
+ render: function() {
+ return new SideNavLayoutView(
+ _.extend({
+ 'searchVent': that.searchVent
+ }, that.preFetchedCollectionLists, that.sharedObj)
+ )
+ }
+ });
+ paramObj = _.extend({ value: value, guid: null }, that.preFetchedCollectionLists, that.sharedObj);
+ App.rNContent.show(new AdministratorLayoutView(paramObj));
+ });
+ },
+ businessMetadataDetailPage: function(guid) {
+ var that = this;
+ require(["views/site/Header", "views/site/SideNavLayoutView", "views/business_metadata/BusinessMetadataContainerLayoutView", ], function(Header, SideNavLayoutView, BusinessMetadataContainerLayoutView) {
+ var paramObj = Utils.getUrlState.getQueryParams();
+ that.renderViewIfNotExists(that.getHeaderOptions(Header));
+ var options = _.extend({
+ guid: guid,
+ value: paramObj,
+ searchVent: that.searchVent,
+ categoryEvent: that.categoryEvent
+ },
+ that.preFetchedCollectionLists,
+ that.sharedObj
+ )
+ that.renderViewIfNotExists({
+ view: App.rSideNav,
+ manualRender: function() {
+ this.view.currentView.selectTab();
+ 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 }));
+ }
+ },
+ render: function() {
+ return new SideNavLayoutView(
+ _.extend({
+ 'searchVent': that.searchVent
+ }, that.preFetchedCollectionLists, that.sharedObj)
+ )
+ }
+ });
+ App.rNContent.show(new BusinessMetadataContainerLayoutView(options));
+ });
+ },
searchResult: function() {
var that = this;
require([
diff --git a/dashboardv2/public/js/templates/administrator/AdministratorLayoutView_tmpl.html b/dashboardv2/public/js/templates/administrator/AdministratorLayoutView_tmpl.html
new file mode 100644
index 0000000..be0d726
--- /dev/null
+++ b/dashboardv2/public/js/templates/administrator/AdministratorLayoutView_tmpl.html
@@ -0,0 +1,40 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<div class="clearfix">
+ <div class="col-sm-12 default-tab">
+ <ul class="nav nav-tabs" data-id="tab-list">
+ <li role="businessMetadata" class="tab active"><a href="#tab-businessMetadata" aria-controls="tab-businessMetadata" role="tab" data-toggle="tab">Business Metadata</a></li>
+ <li role="enum"><a href="#tab-enum" aria-controls="tab-enum" role="tab" data-toggle="tab">Enumerations</a></li>
+ <li role="audit"><a href="#tab-audit" aria-controls="tab-audit" role="tab" data-toggle="tab">Audits</a></li>
+ </ul>
+ </div>
+</div>
+<div class="tab-content admin-details">
+ <div id="tab-businessMetadata" role="businessMetadata" class="tab-pane active animated fadeIn">
+ <div id="r_businessMetadataTableLayoutView">
+ </div>
+ </div>
+ <div id="tab-enum" role="enum" class="tab-pane animated fadeIn">
+ <div id="r_enumTableLayoutView">
+ </div>
+ </div>
+ <div id="tab-audit" role="audit" class="tab-pane animated fadeIn">
+ <div id="r_adminTableLayoutView">
+ </div>
+ </div>
+</div>
+</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/audit/AdminAuditTableLayoutView_tmpl.html b/dashboardv2/public/js/templates/audit/AdminAuditTableLayoutView_tmpl.html
new file mode 100644
index 0000000..f1dc256
--- /dev/null
+++ b/dashboardv2/public/js/templates/audit/AdminAuditTableLayoutView_tmpl.html
@@ -0,0 +1,78 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<div class="tab-content admin-details">
+ <div id="tab-audit" role="adminaudit">
+ <div id="r_auditTableLayoutView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ <div class="position-relative">
+ <div class="tableOverlay"></div>
+ <!-- Not for table Loader its only for initial loading -->
+ <div class="fontLoader">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ <div class="attributeResultContainer form-group ">
+ <button class="btn-action btn-sm attribute-filter-text" data-id='adminAttrFilter'> <i class="fa fa-angle-right"></i> Filters</button>
+ <div class="attribute-filter-container hide">
+ <div class="panel panel-default expand_collapse_panel-icon" data-id="adminRegion">
+ <div class="panel-heading" data-toggle="collapse" href="#collapseAdmin" aria-expanded="true">
+ <h4 class="panel-title">
+ <a>Admin</a>
+ </h4>
+ <div class="btn-group pull-right">
+ <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
+ </div>
+ </div>
+ <div id="collapseAdmin" class="panel-collapse collapse in">
+ <div class="panel-body">
+ <div id='r_attributeQueryBuilderAdmin' class='attribute-querybuilder'>
+ <div class='fontLoader-relative show'><i class='fa fa-refresh fa-spin-custom'></i></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class='attribute-result-footer'>
+ <div type="ok" class="btn btn-atlas ok search" data-id='attrApply'>Apply</div>
+ <div type="ok" class="btn btn-atlas ok" data-id='attrClose'>Close</div>
+ </div>
+ </div>
+ <div class="pull-right admin-type-dropdown">
+ <select class="pull-right form-controlrow-margin-bottom" data-id="adminType"></select>
+ </div>
+ </div>
+ <div class="auditTable" style="display: none">
+ <div class='attr-filter-overlay hide'></div>
+ <div id="r_adminAuditTableLayoutView"></div>
+ </div>
+ </div>
+ </div>
+ <div class="no-data" data-id="showDefault">
+ <div class="position-relative thick-border">
+ <div style="padding-top: 20px; " class="table-responsive tableBorder">
+ <table class="table table-hover backgrid table-quickMenu">
+ <tbody>
+ <tr class="empty">
+ <td colspan="16"><span>No Records found!</span></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/audit/AuditTableLayoutView_tmpl.html b/dashboardv2/public/js/templates/audit/AuditTableLayoutView_tmpl.html
index e03335c..f32dff8 100644
--- a/dashboardv2/public/js/templates/audit/AuditTableLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/audit/AuditTableLayoutView_tmpl.html
@@ -21,12 +21,12 @@
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
<div class="auditTable" style="display: none">
- <div>
- <span class="labelShowRecord pull-left" data-id="pageRecordText"></span>
- </div>
<div id="r_auditTableLayoutView"></div>
- <div class="pagination-box">
- <div class="backgrid-paginator pull-right">
+ <div class="pagination-box row">
+ <div class="col-sm-4">
+ <span class="labelShowRecord pull-left" data-id="pageRecordText"></span>
+ </div>
+ <div class="col-sm-8 backgrid-paginator">
<ul>
<li>
<button type="button" data-id="previousAuditData" title="Previous" disabled=true>
diff --git a/dashboardv2/public/js/templates/audit/CreateAuditTableLayoutView_tmpl.html b/dashboardv2/public/js/templates/audit/CreateAuditTableLayoutView_tmpl.html
index c496f21..3cdbc7f 100644
--- a/dashboardv2/public/js/templates/audit/CreateAuditTableLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/audit/CreateAuditTableLayoutView_tmpl.html
@@ -15,8 +15,8 @@
* limitations under the License.
-->
<h4 style="word-break: break-word;" data-id="name"></h4>
-<div class="panel-group server-stats-container statsContainer " id="accordion">
- <div class="panel panel-default custom-panel expand_collapse_panel-icon hide" data-id="detailsAttribute">
+<div class="panel-group server-stats-container auditStatusContainer clearfix" id="accordion">
+ <div class="panel panel-default custom-panel expand_collapse_panel-icon hide col-sm-5" data-id="detailsAttribute">
<div class="panel-heading" data-toggle="collapse" href="#detailAttributeTableCollapse" aria-expanded="true">
<h4 class="panel-title">
<a>Properties </a>
@@ -37,7 +37,7 @@
</div>
</div>
</div>
- <div class="panel panel-default custom-panel expand_collapse_panel-icon hide" data-id="attributeDetails">
+ <div class="panel panel-default custom-panel expand_collapse_panel-icon hide col-sm-5" data-id="attributeDetails">
<div class="panel-heading" data-toggle="collapse" href="#attributeTableCollapse" aria-expanded="true">
<h4 class="panel-title">
<a data-id="panel-attr-heading">Technical properties </a>
@@ -58,7 +58,7 @@
</div>
</div>
</div>
- <div class="panel panel-default custom-panel expand_collapse_panel-icon hide" data-id="relationShipAttributeDetails">
+ <div class="panel panel-default custom-panel expand_collapse_panel-icon hide col-sm-5" data-id="relationShipAttributeDetails">
<div class="panel-heading" data-toggle="collapse" href="#relationShipAttributeTableCollapse" aria-expanded="true">
<h4 class="panel-title">
<a>Relationship properties </a>
@@ -79,7 +79,7 @@
</div>
</div>
</div>
- <div class="panel panel-default custom-panel expand_collapse_panel-icon hide" data-id="customAttributeDetails">
+ <div class="panel panel-default custom-panel expand_collapse_panel-icon hide col-sm-5" data-id="customAttributeDetails">
<div class="panel-heading" data-toggle="collapse" href="#customAttributeCollapse" aria-expanded="true">
<h4 class="panel-title">
<a>User-defined properties </a>
@@ -100,7 +100,7 @@
</div>
</div>
</div>
- <div class="panel panel-default custom-panel expand_collapse_panel-icon hide" data-id="labelsDetails">
+ <div class="panel panel-default custom-panel expand_collapse_panel-icon hide col-sm-5" data-id="labelsDetails">
<div class="panel-heading" data-toggle="collapse" href="#labelsTableCollapse" aria-expanded="true">
<h4 class="panel-title">
<a>Labels</a>
diff --git a/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttrTableLayoutView_tmpl.html b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttrTableLayoutView_tmpl.html
new file mode 100644
index 0000000..98f30a3
--- /dev/null
+++ b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttrTableLayoutView_tmpl.html
@@ -0,0 +1,47 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<div class="business-metadata-attr-page" data-id="businessMetadataAttrPage">
+ <div class="business-metadata-attr-tableOverlay"></div>
+ <div class=" modal-header" data-id="businessMetadataAttrPageHeader">
+ <h4 class="modal-title" data-id="businessMetadataAttrPageTitle"></h4>
+ </div>
+ <div id="r_modal">
+ </div>
+ <div class="business-metadata-attr-fontLoader">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ <!-- <div class="modal-footer " data-id="modalFooter">
+ <button type="button" class="btn btn-action cancel" data-id="businessMetadataAttrPageCancle">Cancel</button>
+ <button type="button" class="btn btn-atlas ok" data-id="businessMetadataAttrPageOk">Ok</button>
+ </div> -->
+</div>
+<div class="business-metadata-details" data-id="businessMetadataDetailPage">
+ <div class="position-relative">
+ <div class="pull-right inline-content-fr no-padding-left">
+ <div class="inline" data-id="colManager"></div>
+ <div class="inline">
+ <button type="button" data-id="addAttribute" title="Create Business Metadata Attribute" class="btn btn-action btn-sm pull-right btn-loader" style="margin-bottom: 10px;" data-action="createBusinessMetadata">
+ <i class='fa fa-plus'></i> Attributes
+ </button></div>
+ </div>
+ <div class="tableOverlay"></div>
+ <div class='attr-filter-overlay hide'></div>
+ <div class="auditTable business-metadata-details">
+ <div id="r_businessMetadataAttrTableLayoutView"></div>
+ </div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html
new file mode 100644
index 0000000..4b2437d
--- /dev/null
+++ b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html
@@ -0,0 +1,107 @@
+<!--
+ * 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 id="{{modalID}}" class="form-group clearfix business-metadata-attr">
+ <div class="form-group">
+ <div class="col-sm-12 attributePlusData " align="right">
+ <button type="button" class="btn btn-danger btn-sm closeInput" data-id="close"><i class="fa fa-times"></i></button>
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="control-label col-sm-3 required" for="name">Name</label>
+ <div class="col-sm-8">
+ <input class="form-control attributeInput require" data-id="attributeInput" placeholder="Attribute name">
+ </input>
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="control-label col-sm-3 required" for="type">Type</label>
+ <div class="col-sm-8">
+ <select class="form-control dataTypeSelector" data-id="dataTypeSelector">
+ <option selected="selected">string</option>
+ <option>boolean</option>
+ <option>byte</option>
+ <option>short</option>
+ <option>int</option>
+ <option>float</option>
+ <option>double</option>
+ <option>long</option>
+ <option>date</option>
+ <option>enumeration</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="control-label col-sm-3 required" for="type">Search Weight</label>
+ <div class="col-sm-8">
+ <select class="form-control searchWeightSelector" data-id="searchWeightSelector">
+ <option>0</option>
+ <option>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+ <option selected="selected">5</option>
+ <option>6</option>
+ <option>7</option>
+ <option>8</option>
+ <option>9</option>
+ <option>10</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group" data-id="multiValueSelect">
+ <label class="control-label col-sm-3" for="multiValSelect">Enable Multivalues</label>
+ <div class="col-sm-8">
+ <input type="checkbox" class="form-check-input multi-value-select" data-id="multiValueSelectStatus">
+ </div>
+ </div>
+ <div class="form-group enumtype-container" data-id="enumTypeSelectorContainer">
+ <div class="">
+ <label class="control-label col-sm-3 required" for="enumType">Enum Name</label>
+ <div class="col-sm-5">
+ <select class="form-control enumTypeSelector require" data-id="enumTypeSelector" multiple="false">
+ </select>
+ </div>
+ <div class="col-sm-3">
+ <button type="button" class="btn btn-action btn-sm" data-id="createNewEnum" data-action="" title="Create/Update Enum"> <i class="fa fa-pencil"></i> Enum</button>
+ </div>
+ </div>
+ </div>
+ <div class="form-group enumvalue-container" data-id="enumValueSelectorContainer">
+ <div class="">
+ <label class="control-label col-sm-3 required" for="enumVal">Enum Value</label>
+ <div class="col-sm-8">
+ <select class="form-control enumValueSelector" data-id="enumValueSelector" multiple="true">
+ </select>
+ </div>
+ </div>
+ </div>
+ <div class="form-group" data-id="stringLengthContainer">
+ <div class="stringlength-container">
+ <label class="control-label col-sm-3 required" for="name">Max length</label>
+ <div class="col-sm-8">
+ <input type="number" class="form-control stringLengthVal require" data-id="stringLength" placeholder="Maximum length">
+ </div>
+ </div>
+ </div>
+ <div class="form-group entity-businessMetadata-selector">
+ <label class="control-label col-sm-3" for="name">Applicable Types</label>
+ <div class="col-sm-8">
+ <select class="form-control entityTypeSelector" data-id="entityTypeSelector" multiple="multiple">
+ </select>
+ </div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/business_metadata/BusinessMetadataContainerLayoutView_tmpl.html b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataContainerLayoutView_tmpl.html
new file mode 100644
index 0000000..d964202
--- /dev/null
+++ b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataContainerLayoutView_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 id="r_businessMetadataDetailContainer"></div>
+ <div id="r_businessMetadataAttrContainer" class="col-sm-12"></div>
+</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/business_metadata/BusinessMetadataDetailLayoutView_tmpl.html b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataDetailLayoutView_tmpl.html
new file mode 100644
index 0000000..d8a2b5b
--- /dev/null
+++ b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataDetailLayoutView_tmpl.html
@@ -0,0 +1,26 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<div class="page-title clearfix">
+ <div class="fontLoader">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ <div class="tagDetail clearfix form-horizontal col-sm-12">
+ <h1 class="title"><span data-id="title"></span></h1>
+ <p class="form-group col-sm-12" data-id="description"></p>
+ </div>
+</div>
+</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/business_metadata/BusinessMetadataTableLayoutView_tmpl.html b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataTableLayoutView_tmpl.html
new file mode 100644
index 0000000..154d5b8
--- /dev/null
+++ b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataTableLayoutView_tmpl.html
@@ -0,0 +1,47 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<div class="business-metadata-attr-page" data-id="businessMetadataAttrPage">
+ <div class="business-metadata-attr-tableOverlay"></div>
+ <div class=" modal-header" data-id="businessMetadataAttrPageHeader">
+ <h4 class="modal-title" data-id="businessMetadataAttrPageTitle"></h4>
+ </div>
+ <div id="r_modal">
+ </div>
+ <div class="business-metadata-attr-fontLoader">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ <!-- <div class="modal-footer " data-id="modalFooter">
+ <button type="button" class="btn btn-action cancel" data-id="businessMetadataAttrPageCancle">Cancel</button>
+ <button type="button" class="btn btn-atlas ok" data-id="businessMetadataAttrPageOk">Ok</button>
+ </div> -->
+</div>
+<div class="business-metadata-details" data-id="businessMetadataDetailPage">
+ <div class="position-relative">
+ <div class="pull-right inline-content-fr no-padding-left">
+ <div class="inline" data-id="colManager"></div>
+ <div class="inline">
+ <button type="button" data-id="createBusinessMetadata" title="Create Business Metadata" class="btn btn-action btn-sm pull-right btn-loader" style="margin-bottom: 10px;" data-action="createBusinessMetadata">
+ <i class='fa fa-plus'></i> Create Business Metadata
+ </button></div>
+ </div>
+ <div class="tableOverlay"></div>
+ <div class='attr-filter-overlay hide'></div>
+ <div class="auditTable business-metadata-details">
+ <div id="r_businessMetadataTableLayoutView"></div>
+ </div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/business_metadata/CreateBusinessMetadataLayoutView_tmpl.html b/dashboardv2/public/js/templates/business_metadata/CreateBusinessMetadataLayoutView_tmpl.html
new file mode 100644
index 0000000..a78614d
--- /dev/null
+++ b/dashboardv2/public/js/templates/business_metadata/CreateBusinessMetadataLayoutView_tmpl.html
@@ -0,0 +1,53 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<div class="fontLoader">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+</div>
+<form class="hide form-horizontal" data-id="createForm" style="width: 70%;margin: 0 auto;">
+ {{#if fromTable}}
+ <div class="form-group">
+ <label class="control-label col-sm-2 {{#if create}}required{{/if}}" for="name">Name</label>
+ {{#if create}}
+ <div class="col-sm-10">
+ <input class="form-control businessMetadata-name require" data-id="name" placeholder="Name(required)" autofocus />
+ </div>
+ {{else}}
+ <span class="ellipsis-with-margin control-label text-left col-sm-10" data-id="title"></span> {{/if}}
+ </div>
+ <div class="form-group">
+ <label class="control-label col-sm-2" for="description">Description</label>
+ <div class="col-sm-10">
+ <input class="form-control" data-id="description" value="{{description}}" placeholder="Description" />
+ </div>
+ </div>
+ {{/if}}
+ <div class="form-group">
+ <!-- <h4 class="col-sm-6">Attributes</h4> -->
+ {{#if isEditAttr}}
+ <div class="col-sm-12 no-padding-left">
+ <button title="Add Business Metadata attribute" type="button" class="btn btn-action btn-sm pull-left" data-id="attributeData"><i class="fa fa-plus"></i> Add Business Metadata attribute</button>
+ </div>
+ {{/if}}
+ </div>
+ <div data-id="addAttributeDiv">
+ </div>
+ </div>
+</form>
+<div class="modal-footer " data-id="modalFooter">
+ <button type="button" class="btn btn-action cancel" data-id="businessMetadataAttrPageCancle">Cancel</button>
+ <button type="button" class="btn btn-atlas ok" data-id="businessMetadataAttrPageOk">Ok</button>
+</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/business_metadata/EnumCreateUpdateItemView_tmpl.html b/dashboardv2/public/js/templates/business_metadata/EnumCreateUpdateItemView_tmpl.html
new file mode 100644
index 0000000..be0ab81
--- /dev/null
+++ b/dashboardv2/public/js/templates/business_metadata/EnumCreateUpdateItemView_tmpl.html
@@ -0,0 +1,39 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<div class="form-horizontal form-group clearfix enum-attr">
+ <div class="form-group" data-id="enumTypeSelectorContainer">
+ <label class="control-label col-sm-3 required" for="enumType">Enum Name</label>
+ <div class="col-sm-8">
+ <select class="form-control enumTypeSelector" data-id="enumSelector">
+ </select>
+ </div>
+ </div>
+ <div class="form-group " data-id="enumValueSelectorContainer">
+ <label class="control-label col-sm-3 required" for="enumVal">Enum Value</label>
+ <div class="col-sm-8">
+ <select class="form-control enumValueSelector" data-id="valueSelector" multiple="multiple">
+ </select>
+ </div>
+ </div>
+ <div class="form-group " data-id="enumFooter">
+ <label class="control-label col-sm-3" for="enumVal"></label>
+ <div class="col-sm-8">
+ <button type="button" data-id="enumCancleBtn" class="btn btn-action cancel">Cancel</button>
+ <button type="button" data-id="enumOkBtn" class="btn btn-atlas ok">Update</button>
+ </div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/common/Modal.html b/dashboardv2/public/js/templates/common/Modal.html
index cf409ef..207722e 100644
--- a/dashboardv2/public/js/templates/common/Modal.html
+++ b/dashboardv2/public/js/templates/common/Modal.html
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
-->
-<div class="modal-dialog {{mainClass}} " style="width:{{width}}" role="document">
+<div class="modal-dialog {{mainClass}}{{modal-full-screen}} " style="width:{{width}}" role="document">
<div class="modal-content">
{{#if title}}
<div class="modal-header">
diff --git a/dashboardv2/public/js/templates/common/TableLayout_tmpl.html b/dashboardv2/public/js/templates/common/TableLayout_tmpl.html
index 60ccc2f..db1f0b3 100644
--- a/dashboardv2/public/js/templates/common/TableLayout_tmpl.html
+++ b/dashboardv2/public/js/templates/common/TableLayout_tmpl.html
@@ -22,11 +22,7 @@
{{/unless}}
</div>
</div>
- {{#if includePagination}}
- <div class="clearfix banded">
- <div data-id="r_footerRecords" class="margin-top-10"></div>
- </div>
- {{/if}} {{#if includeAtlasPagination}}
+ {{#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>
@@ -43,7 +39,10 @@
</div>
{{#if includePagination}}
<div class="row clearfix banded pagination-box">
- <div class="col-sm-offset-4 col-sm-8">
+ <div class="col-sm-4">
+ <div data-id="r_footerRecords" class="margin-top-10"></div>
+ </div>
+ <div class="col-sm-8">
<div class="inline-content-fr">
<div data-id="r_pagination" data-id="paginationDiv" class="inline"></div>
{{#if includeGotoPage}}
diff --git a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
index afff90d..3747f8e 100644
--- a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
@@ -19,13 +19,13 @@
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
<div class="entityDetail form-horizontal col-sm-12">
- <h1 class="title row isIncomplete">
+ <h1 class="title isIncomplete">
<div data-id="entityIcon" class="entity-icon-box position-relative"></div>
<span data-id="title"></span>
</h1> {{#if entityUpdate}}
<!-- <div data-id="editButtonContainer" class="pull-right"></div> -->
{{/if}}
- <div class="form-group">
+ <div class="form-group col-md-12">
<span class="control-label-sm-pr pull-left">Classifications:</span>
<div class="pull-left" data-id="tagList">
<button class="btn btn-action btn-sm" title="Add Classification" data-id="addTag">
@@ -33,7 +33,7 @@
</button>
</div>
</div>
- <div class="form-group termBox">
+ <div class="form-group termBox col-md-12">
<span class="control-label-sm-pr pull-left">Terms:</span>
<div class="pull-left" data-id="termList">
<button class="btn btn-action btn-sm" title="Add Term" data-id="addTerm">
@@ -41,7 +41,7 @@
</button>
</div>
</div>
- <div class="form-group" style="display: none;" data-id="propagatedTagDiv">
+ <div class="form-group col-md-12" style="display: none;" data-id="propagatedTagDiv">
<span class="control-label-sm-pr pull-left">Propagated Classifications:</span>
<div class="pull-left" data-id="propagatedTagList">
</div>
@@ -62,70 +62,81 @@
</div>
</div>
</div>
-<div>
- <div class="tab-content">
- <div id="tab-details" role="properties" class="tab-pane active animated fadeIn">
- <div class="row">
- <div class="col-md-6">
- <div id="r_entityDetailTableLayoutView">
- <div class="fontLoader-relative">
- <i class="fa fa-refresh fa-spin-custom"></i>
- </div>
+<div class="tab-content">
+ <div id="tab-details" role="properties" class="tab-pane active animated fadeIn">
+ <div class="row">
+ <div class="col-md-6">
+ <div id="r_entityDetailTableLayoutView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
- <div class="col-md-6">
- <div id="r_entityUserDefineView"></div>
- <div id="r_entityLabelDefineView"></div>
+ </div>
+ <div class="col-md-6 loader-row">
+ <div id="r_entityUserDefineView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ </div>
+ <div id="r_entityLabelDefineView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ </div>
+ <div id="r_entityBusinessMetadataView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
</div>
</div>
</div>
- <div id="tab-lineage" role="lineage" class="tab-pane animated fadeIn">
- <div id="r_lineageLayoutView" class="animated position-relative" align="center">
- <div class="fontLoader-relative">
- <i class="fa fa-refresh fa-spin-custom"></i>
- </div>
+ </div>
+ <div id="tab-lineage" role="lineage" class="tab-pane animated fadeIn">
+ <div id="r_lineageLayoutView" class="animated position-relative" align="center">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
- <div id="tab-relationship" role="relationship" class="tab-pane animated fadeIn">
- <div id="r_relationshipLayoutView" class="animated position-relative">
- <div class="fontLoader-relative">
- <i class="fa fa-refresh fa-spin-custom"></i>
- </div>
+ </div>
+ <div id="tab-relationship" role="relationship" class="tab-pane animated fadeIn">
+ <div id="r_relationshipLayoutView" class="animated position-relative">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
- <div id="tab-tagTable" role="classification" class="tab-pane animated fadeIn">
- <div id="r_tagTableLayoutView">
- <div class="fontLoader-relative">
- <i class="fa fa-refresh fa-spin-custom"></i>
- </div>
+ </div>
+ <div id="tab-tagTable" role="classification" class="tab-pane animated fadeIn">
+ <div id="r_tagTableLayoutView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
- <div id="tab-audit" role="audit" class="tab-pane animated fadeIn">
- <div id="r_auditTableLayoutView">
- <div class="fontLoader-relative">
- <i class="fa fa-refresh fa-spin-custom"></i>
- </div>
+ </div>
+ <div id="tab-audit" role="audit" class="tab-pane animated fadeIn">
+ <div id="r_auditTableLayoutView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
</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 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 id="tab-schema" role="schema" class="tab-pane animated fadeIn">
- <div id="r_schemaTableLayoutView">
- <div class="fontLoader-relative">
- <i class="fa fa-refresh fa-spin-custom"></i>
- </div>
+ </div>
+ <div id="tab-schema" role="schema" class="tab-pane animated fadeIn">
+ <div id="r_schemaTableLayoutView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
- <div id="tab-profile" role="profile" class="tab-pane animated fadeIn">
- <div id="r_profileLayoutView">
- <div class="fontLoader-relative">
- <i class="fa fa-refresh fa-spin-custom"></i>
- </div>
+ </div>
+ <div id="tab-profile" role="profile" class="tab-pane animated fadeIn">
+ <div id="r_profileLayoutView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
</div>
diff --git a/dashboardv2/public/js/templates/entity/EntityBusinessMetaDataItemView_tmpl.html b/dashboardv2/public/js/templates/entity/EntityBusinessMetaDataItemView_tmpl.html
new file mode 100644
index 0000000..3338fd5
--- /dev/null
+++ b/dashboardv2/public/js/templates/entity/EntityBusinessMetaDataItemView_tmpl.html
@@ -0,0 +1,44 @@
+<!--
+ * 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.
+-->
+{{#ifCond model "has" "isNew"}}
+<table class="custom-table" style="font-weight: 100;">
+ <tr class="custom-tr">
+ <td class="custom-col-1">
+ {{{callmyfunction getBusinessMetadataDroupdown businessMetadataCollection}}}
+ </td>
+ <td class="custom-col-0"> : </td>
+ <td class="custom-col-1" data-id="value">
+ <input type="text" data-key disabled class="form-control">
+ </td>
+ <td class="custom-col-2 btn-group">
+ <button class="btn btn-default btn-sm" data-id="deleteItem">
+ <i class="fa fa-minus"> </i>
+ </button>
+ <button class="btn btn-default btn-sm" data-id="addItem">
+ <i class="fa fa-plus"> </i>
+ </button>
+ </td>
+ </tr>
+</table>
+{{else}}
+<hr />
+<ul class="business-metadata-tree-parent">
+ <li>{{model.__internal_UI_businessMetadataName}}</li>
+ <li class="business-metadata-tree-child" data-id="businessMetadataTreeChild">
+ </li>
+</ul>
+{{/ifCond}}
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/entity/EntityBusinessMetaDataView_tmpl.html b/dashboardv2/public/js/templates/entity/EntityBusinessMetaDataView_tmpl.html
new file mode 100644
index 0000000..0e4c2aa
--- /dev/null
+++ b/dashboardv2/public/js/templates/entity/EntityBusinessMetaDataView_tmpl.html
@@ -0,0 +1,42 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<div class="panel panel-default custom-panel expand_collapse_panel-icon">
+ <div class="panel-heading" data-toggle="collapse" href="#businessMetadataCollapse" aria-expanded="false" style="width: 70%;">
+ <h4 class="panel-title">
+ <a>Business Metadata</a>
+ </h4>
+ <div class="btn-group pull-left">
+ <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
+ </div>
+ </div>
+ <div class="panel-actions">
+ <button class="btn btn-action btn-sm" data-id="addBusinessMetadata">Add</button>
+ <button class="btn btn-action btn-sm" style="display: none;" data-id="saveBusinessMetadata">Save</button>
+ <button class="btn btn-action btn-sm" style="display: none;" data-id="cancel">Cancel</button>
+ </div>
+ <div id="businessMetadataCollapse" class="panel-collapse collapse">
+ <div class="panel-body">
+ <div data-id="businessMetadataTree"></div>
+ <div class="editBox" style="display: none;">
+ <div class="form-group">
+ <a href="javascript:void(0)" class="btn btn-action btn-sm" data-id="addItem" data-type="addAttrButton">Add New Attribute</a>
+ </div>
+ <ul class="business-metadata-tree-parent" data-id="itemView"></ul>
+ </div>
+ </div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/glossary/GlossaryDetailLayoutView_tmpl.html b/dashboardv2/public/js/templates/glossary/GlossaryDetailLayoutView_tmpl.html
index 05f6af9..61a134c 100644
--- a/dashboardv2/public/js/templates/glossary/GlossaryDetailLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/glossary/GlossaryDetailLayoutView_tmpl.html
@@ -72,30 +72,28 @@
{{/if}}
</div>
</div>
-<div class="container-fluid">
- {{#if isTermView}}
- <div class="tab-content">
- <div id="tab-entities" role="entities" class="tab-pane active animated fadeIn">
- <div id="r_searchResultLayoutView">
- <div class="fontLoader-relative">
- <i class="fa fa-refresh fa-spin-custom"></i>
- </div>
- </div>
- </div>
- <div id="tab-tagTable" role="classification" class="tab-pane animated fadeIn">
- <div id="r_tagTableLayoutView">
- <div class="fontLoader-relative">
- <i class="fa fa-refresh fa-spin-custom"></i>
- </div>
- </div>
- </div>
- <div id="tab-relatedTerm" role="relatedTerm" class="tab-pane animated fadeIn">
- <div id="r_relationLayoutView">
- <div class="fontLoader-relative">
- <i class="fa fa-refresh fa-spin-custom"></i>
- </div>
+{{#if isTermView}}
+<div class="tab-content">
+ <div id="tab-entities" role="entities" class="tab-pane active animated fadeIn">
+ <div id="r_searchResultLayoutView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
</div>
- {{/if}}
-</div>
\ No newline at end of file
+ <div id="tab-tagTable" role="classification" class="tab-pane animated fadeIn">
+ <div id="r_tagTableLayoutView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ </div>
+ </div>
+ <div id="tab-relatedTerm" role="relatedTerm" class="tab-pane animated fadeIn">
+ <div id="r_relationLayoutView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ </div>
+ </div>
+</div>
+{{/if}}
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/schema/SchemaTableLayoutView_tmpl.html b/dashboardv2/public/js/templates/schema/SchemaTableLayoutView_tmpl.html
index 3aadc67..d77544f 100644
--- a/dashboardv2/public/js/templates/schema/SchemaTableLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/schema/SchemaTableLayoutView_tmpl.html
@@ -16,7 +16,7 @@
-->
<div class="position-relative">
<div class="tableOverlay"></div>
- <div class="inline-content-fr table-action-btn">
+ <div class="inline-content-fr">
<div class="clearfix inline">
<a href="javascript:void(0)" title="Assign Classification" class="inputAssignTag multiSelectTag assignTag btn btn-action btn-sm" style="display:none" data-id="addAssignTag"><i class="fa fa-plus"></i> Classification</a>
</div>
diff --git a/dashboardv2/public/js/templates/search/SearchDetailLayoutView_tmpl.html b/dashboardv2/public/js/templates/search/SearchDetailLayoutView_tmpl.html
index 0f383df..289830c 100644
--- a/dashboardv2/public/js/templates/search/SearchDetailLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/search/SearchDetailLayoutView_tmpl.html
@@ -14,12 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
-->
-<div class="container-fluid gray-bg">
+<div class="container-fluid">
<div class="row">
<div class="col-sm-custom">
- <div class="atlast-tabbable">
- <div id="r_searchResultLayoutView"></div>
- </div>
+ <div id="r_searchResultLayoutView"></div>
</div>
</div>
</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/search/SearchQuery_tmpl.html b/dashboardv2/public/js/templates/search/SearchQuery_tmpl.html
index 05c2a61..ced907f 100644
--- a/dashboardv2/public/js/templates/search/SearchQuery_tmpl.html
+++ b/dashboardv2/public/js/templates/search/SearchQuery_tmpl.html
@@ -15,7 +15,7 @@
* limitations under the License.
-->
<div id="r_queryBuilder">
- <div class="fontLoader">
+ <div class="fontLoader-relative show">
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
diff --git a/dashboardv2/public/js/templates/search/SearchResultLayoutView_tmpl.html b/dashboardv2/public/js/templates/search/SearchResultLayoutView_tmpl.html
index 605be92..fc780d8 100644
--- a/dashboardv2/public/js/templates/search/SearchResultLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/search/SearchResultLayoutView_tmpl.html
@@ -36,12 +36,9 @@
</div>
</div>
</div>
- <div class="{{#unless isGlossaryView}}row well{{/unless}}" style="padding-top: 0px;">
+ <div style="padding-top: 0px;">
<div class="row form-group pagination-box filter-box" style="display: none;">
- <div class="col-sm-3">
- <span class="labelShowRecord pull-left" data-id="pageRecordText"> </span>
- </div>
- <div class="col-sm-9 inline-content-fr no-padding-left">
+ <div class="col-sm-12 inline-content-fr no-padding-left">
<div class="inline" data-id="colManager"></div>
<div class="inline">
<a href="javascript:void(0)" class="multiSelectTag assignTag btn btn-action btn-sm" style="display:none" title="Assign Classification" data-id="addAssignTag"><i class="fa fa-plus"></i> Classification</a>
@@ -80,13 +77,16 @@
</div>
{{/if}}
</div>
- <div class="row pagination-box searach-result-pagination" style="display: none">
- <div class="col-sm-offset-4 col-sm-8">
+ <div class="pagination-box searach-result-pagination row" style="display: none">
+ <div class="col-sm-4">
+ <span class="labelShowRecord pull-left" data-id="pageRecordText"> </span>
+ </div>
+ <div class="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>
+ <button type="button" data-id="previousData" title="Previous" disabled="true">
<i class="fa fa-angle-left" aria-hidden="true"></i>
</button>
</li>
@@ -104,7 +104,9 @@
<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>
+ <button class="btn btn-default" type="button" data-id="gotoPagebtn" title="Goto Page" disabled="disabled">
+ Go!
+ </button>
</span>
</div>
</div>
@@ -112,8 +114,7 @@
<div class="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>
+ <select data-id="showPage" multiple="multiple" class="form-control"> </select>
</div>
</div>
</div>
diff --git a/dashboardv2/public/js/templates/site/Header.html b/dashboardv2/public/js/templates/site/Header.html
index 3467b4d..1510c19 100644
--- a/dashboardv2/public/js/templates/site/Header.html
+++ b/dashboardv2/public/js/templates/site/Header.html
@@ -22,7 +22,7 @@
<li>
<a href="javascript:void(0);" data-id="menuHamburger"><i class="fa fa-bars"></i></a>
</li>
- <li class="details-backbutton"><a href="javascript:void(0);" data-id="backButton"><i class="fa fa-chevron-left"></i> Back To Results</a></li>
+ <li class="details-backbutton"><a href="javascript:void(0);" data-id="backButton"><i class="fa fa-chevron-left"></i><span> Back To Results</span></a></li>
</ul>
</td>
<td class="global-search-container">
@@ -41,6 +41,7 @@
<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 role="separator" class="divider"></li>
<li><a data-id="uiSwitch" href="javascript:void(0)">Switch to New</a></li>
diff --git a/dashboardv2/public/js/templates/tag/TagDetailLayoutView_tmpl.html b/dashboardv2/public/js/templates/tag/TagDetailLayoutView_tmpl.html
index 1a5a42d..80696d9 100644
--- a/dashboardv2/public/js/templates/tag/TagDetailLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/tag/TagDetailLayoutView_tmpl.html
@@ -16,12 +16,10 @@
-->
<div id="r_TagAttributeDetailLayoutView">
</div>
-<div class="container-fluid gray-bg">
+<div class="container-fluid">
<div class="row">
<div class="col-sm-custom">
- <div class="atlast-tabbable">
- <div id="r_searchResultLayoutView"></div>
- </div>
+ <div id="r_searchResultLayoutView"></div>
</div>
</div>
</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/tag/TagDetailTableLayoutView_tmpl.html b/dashboardv2/public/js/templates/tag/TagDetailTableLayoutView_tmpl.html
index cfe74c2..b84a0d0 100644
--- a/dashboardv2/public/js/templates/tag/TagDetailTableLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/tag/TagDetailTableLayoutView_tmpl.html
@@ -16,7 +16,7 @@
-->
<div class="position-relative">
<div class="tableOverlay"></div>
- <div class="inline-content-fr table-action-btn">
+ <div class="inline-content-fr">
<div class="inline">
<label class="checkbox-inline btn">
<input type="checkbox" data-id="checkPropagtedTag" class="input" checked="true" name="queryType" value="text" name="check" value="1" /> Show Propagated Classifications</label>
diff --git a/dashboardv2/public/js/utils/Globals.js b/dashboardv2/public/js/utils/Globals.js
index a454113..bb515f0 100644
--- a/dashboardv2/public/js/utils/Globals.js
+++ b/dashboardv2/public/js/utils/Globals.js
@@ -28,7 +28,8 @@
stateChanged: false,
tagUrl: "#!/tag",
searchUrl: "#!/search",
- glossaryUrl: "#!/glossary"
+ glossaryUrl: "#!/glossary",
+ administratorUrl: "#!/administrator"
},
detailPageState: {}
};
diff --git a/dashboardv2/public/js/utils/Helper.js b/dashboardv2/public/js/utils/Helper.js
index dc06e8d..dd7b0b2 100644
--- a/dashboardv2/public/js/utils/Helper.js
+++ b/dashboardv2/public/js/utils/Helper.js
@@ -113,6 +113,81 @@
$("body").on('click', '.btn', function() {
$(this).blur();
});
+ $.fn.select2.amd.define("TagHideDeleteButtonAdapter", [
+ "select2/utils",
+ "select2/selection/multiple",
+ "select2/selection/placeholder",
+ "select2/selection/eventRelay",
+ "select2/selection/search",
+ ],
+ function(Utils, MultipleSelection, Placeholder, EventRelay, SelectionSearch) {
+
+ // Decorates MultipleSelection with Placeholder
+
+ var adapter = Utils.Decorate(MultipleSelection, Placeholder);
+ adapter = Utils.Decorate(adapter, SelectionSearch);
+ adapter = Utils.Decorate(adapter, EventRelay);
+
+ adapter.prototype.render = function() {
+ // Use selection-box from SingleSelection adapter
+ // This implementation overrides the default implementation
+ var $search = $(
+ '<li class="select2-search select2-search--inline">' +
+ '<input class="select2-search__field" type="search" tabindex="-1"' +
+ ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
+ ' spellcheck="false" role="textbox" aria-autocomplete="list" />' +
+ '</li>'
+ );
+
+ this.$searchContainer = $search;
+ this.$search = $search.find('input');
+ var $selection = MultipleSelection.prototype.render.call(this);
+ this._transferTabIndex();
+ return $selection;
+ };
+
+ adapter.prototype.update = function(data) {
+ // copy and modify SingleSelection adapter
+ var that = this;
+ this.clear();
+ if (data.length === 0) {
+ this.$selection.find('.select2-selection__rendered')
+ .append(this.$searchContainer);
+ this.$search.attr('placeholder', this.options.get("placeholder"));
+ return;
+ }
+ this.$search.attr('placeholder', '');
+ var $rendered = this.$selection.find('.select2-selection__rendered'),
+ $selectionContainer = [];
+ if (data.length > 0) {
+ _.each(data, function(obj) {
+ var $container = $('<li class="select2-selection__choice"></li>'),
+ formatted = that.display(obj, $rendered),
+ $remove = $('<span class="select2-selection__choice__remove" role="presentation">×</span>'),
+ allowRemoveAttr = $(obj.element).data("allowremove"),
+ allowRemove = obj.allowRemove === undefined ? allowRemoveAttr : obj.allowRemove;
+ if (allowRemove === undefined || allowRemove !== false) {
+ $container.append($remove);
+ }
+ $container.data("data", obj);
+ $container.append(formatted);
+ $selectionContainer.push($container);
+ });
+ Utils.appendMany($rendered, $selectionContainer);
+ }
+
+
+ var searchHadFocus = this.$search[0] == document.activeElement;
+ this.$search.attr('placeholder', '');
+ this.$selection.find('.select2-selection__rendered')
+ .append(this.$searchContainer);
+ this.resizeSearch();
+ if (searchHadFocus) {
+ this.$search.focus();
+ }
+ };
+ return adapter;
+ });
if ($.fn.select2) {
$.fn.select2.amd.define("ServiceTypeFilterDropdownAdapter", [
diff --git a/dashboardv2/public/js/utils/Overrides.js b/dashboardv2/public/js/utils/Overrides.js
index ae61f09..33328f0 100644
--- a/dashboardv2/public/js/utils/Overrides.js
+++ b/dashboardv2/public/js/utils/Overrides.js
@@ -96,7 +96,9 @@
});
}
if (modelValue.get('width')) that.$el.find('.' + modelValue.get('name')).css('min-width', modelValue.get('width') + 'px');
+ if (modelValue.get('fixWidth')) that.$el.find('.' + modelValue.get('name')).css('width', modelValue.get('fixWidth') + 'px');
if (modelValue.get('toolTip')) that.$el.find('.' + modelValue.get('name')).attr('title', modelValue.get('toolTip'));
+ if (modelValue.get('headerClassName')) that.$el.find('.' + modelValue.get('name').replace(".", "\\.")).addClass(modelValue.get('headerClassName'));
});
return this;
}
@@ -162,6 +164,95 @@
return this;
};
+ /*
+ backgrid-expandable-cell
+ https://github.com/cime/backgrid-expandable-cell
+
+ Copyright (c) 2014 Andrej Cimperšek
+ Licensed under the MIT @license.
+ */
+ Backgrid.ExpandableCell = Backgrid.Cell.extend({
+ accordion: true,
+ toggle: '<i style="cursor: pointer;" class="glyphicon toggle pull-left"></i>',
+ toggleClass: 'toggle',
+ toggleExpandedClass: 'fa fa-angle-down',
+ toggleCollapsedClass: 'fa fa-angle-right',
+ trClass: 'expandable',
+ tdClass: 'expandable-content',
+ events: {
+ 'click': 'setToggle'
+ },
+ initialize: function(options) {
+ if (options.accordion) {
+ this.accordion = options.accordion;
+ }
+
+ this.column = options.column;
+ if (!(this.column instanceof Backgrid.Column)) {
+ this.column = new Backgrid.Column(this.column);
+ }
+
+ var column = this.column,
+ model = this.model,
+ $el = this.$el;
+
+ if (Backgrid.callByNeed(column.renderable(), column, model)) $el.addClass("renderable");
+ },
+
+ render: function() {
+ /* follow along with the original render really... */
+ this.$el.empty();
+
+ this.$toggleEl = $(this.toggle).addClass(this.toggleClass).addClass(this.toggleCollapsedClass);
+
+ this.$el.append(this.$toggleEl);
+
+ this.delegateEvents();
+
+ return this;
+ },
+
+ setToggle: function() {
+ var detailsRow = this.$el.data('details');
+ var toggle = this.$toggleEl;
+
+ /* if there's details data already stored, then we'll remove it */
+ if (detailsRow) {
+ $(detailsRow).remove();
+ this.$el.data('details', null);
+ toggle.removeClass(this.toggleExpandedClass).addClass(this.toggleCollapsedClass);
+ } else {
+ if (this.accordion) {
+ var table = this.$el.closest('table');
+ $('.' + this.toggleClass, table).filter('.' + this.toggleExpandedClass).click();
+ }
+
+ var renderableColumns = this.$el.closest('table').find('th.renderable').length;
+ var isRenderable = false;
+ var cellClass = this.tdClass;
+
+ if (Backgrid.callByNeed(this.column.renderable(), this.column, this.model)) {
+ isRenderable = true;
+ cellClass += ' renderable';
+ }
+
+ /* build a jquery object for the new row... */
+ detailsRow = $('<tr class="' + this.trClass + '"></td><td class="' + cellClass + '" colspan="' + (renderableColumns - 1) + '"></td></tr>');
+
+ /* Inject new row */
+ this.$el.closest('tr').after(detailsRow);
+
+ /* Call expand function */
+ this.column.get('expand')(detailsRow.find('td.' + this.tdClass), this.model);
+
+ this.$el.data('details', detailsRow);
+
+ toggle.removeClass(this.toggleCollapsedClass).addClass(this.toggleExpandedClass);
+ }
+
+ return this;
+ }
+ });
// Backgrid patch
Backgrid.Header.prototype.initialize = BackgridHeaderInitializeMethod;
diff --git a/dashboardv2/public/js/utils/UrlLinks.js b/dashboardv2/public/js/utils/UrlLinks.js
index 56a4a47..3bfef85 100644
--- a/dashboardv2/public/js/utils/UrlLinks.js
+++ b/dashboardv2/public/js/utils/UrlLinks.js
@@ -37,12 +37,18 @@
classificationDefApiUrl: function(name) {
return this.getDefApiUrl('classification', name);
},
+ businessMetadataDefApiUrl: function(name) {
+ return this.getDefApiUrl('business_metadata', name);
+ },
enumDefApiUrl: function(name) {
return this.getDefApiUrl('enum', name);
},
metricsApiUrl: function() {
return this.baseUrl + '/admin/metrics'
},
+ migrationStatusApiUrl: function() {
+ return this.baseUrl + '/admin/status'
+ },
rootEntityDefUrl: function(name) {
return this.baseUrlV2 + '/types/entitydef/name/' + name;
},
@@ -99,6 +105,11 @@
return this.baseUrlV2 + '/entity/bulk/classification';
}
},
+ entitiesBusinessMetadataApiUrl: function(guid) {
+ if (guid) {
+ return this.baseUrlV2 + '/entity/guid/' + guid + '/businessmetadata?isOverwrite=true';
+ }
+ },
entityCollectionaudit: function(guid) {
return this.baseUrlV2 + '/entity/' + guid + '/audit';
},
@@ -232,6 +243,9 @@
},
sessionApiUrl: function() {
return this.baseUrl + '/admin/session';
+ },
+ adminApiUrl: function() {
+ return this.baseUrl + '/admin/audits';
}
});
diff --git a/dashboardv2/public/js/utils/Utils.js b/dashboardv2/public/js/utils/Utils.js
index 4f1a002..345fd88 100644
--- a/dashboardv2/public/js/utils/Utils.js
+++ b/dashboardv2/public/js/utils/Utils.js
@@ -352,6 +352,8 @@
urlUpdate['searchUrl'] = options.url;
} else if (Utils.getUrlState.isGlossaryTab(options.url)) {
urlUpdate['glossaryUrl'] = options.url;
+ } else if (Utils.getUrlState.isAdministratorTab(options.url)) {
+ urlUpdate['administratorUrl'] = options.url;
}
$.extend(Globals.saveApplicationState.tabState, urlUpdate);
}
@@ -387,12 +389,22 @@
matchString: "tag"
});
},
+ isBSDetail: function(url) {
+ var quey = this.getQueryUrl(url);
+ return (quey.queyParams[0].indexOf("administrator/businessMetadata")) > -1 ? true : false;
+ },
isSearchTab: function(url) {
return this.checkTabUrl({
url: url,
matchString: "search"
});
},
+ isAdministratorTab: function(url) {
+ return this.checkTabUrl({
+ url: url,
+ matchString: "administrator"
+ });
+ },
isGlossaryTab: function(url) {
return this.checkTabUrl({
url: url,
@@ -552,6 +564,27 @@
}
}
+
+ Utils.backButtonClick = function() {
+ var queryParams = Utils.getUrlState.getQueryParams(),
+ urlPath = "searchUrl";
+ if (queryParams && queryParams.from) {
+ if (queryParams.from == "classification") {
+ urlPath = "tagUrl";
+ } else if (queryParams.from == "glossary") {
+ urlPath = "glossaryUrl";
+ } else if (queryParams.from == "bm") {
+ urlPath = "administratorUrl";
+ }
+ }
+ Utils.setUrl({
+ url: Globals.saveApplicationState.tabState[urlPath],
+ mergeBrowserUrl: false,
+ trigger: true,
+ updateTabState: true
+ });
+ }
+
Utils.showTitleLoader = function(loaderEl, titleBoxEl) {
loaderEl.css ? loaderEl.css({
'display': 'block',
diff --git a/dashboardv2/public/js/views/administrator/AdministratorLayoutView.js b/dashboardv2/public/js/views/administrator/AdministratorLayoutView.js
new file mode 100644
index 0000000..869371c
--- /dev/null
+++ b/dashboardv2/public/js/views/administrator/AdministratorLayoutView.js
@@ -0,0 +1,118 @@
+/**
+ * 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/administrator/AdministratorLayoutView_tmpl',
+ 'collection/VEntityList',
+ 'models/VSearch',
+ 'utils/Utils',
+ 'utils/Enums',
+ 'utils/UrlLinks',
+ 'utils/CommonViewFunction'
+], function(require, Backbone, AdministratorLayoutView_tmpl, VEntityList, VSearch, Utils, Enums, UrlLinks, CommonViewFunction) {
+ 'use strict';
+
+ var AdministratorLayoutView = Backbone.Marionette.LayoutView.extend(
+ /** @lends AuditTableLayoutView */
+ {
+ _viewName: 'AdministratorLayoutView',
+
+ template: AdministratorLayoutView_tmpl,
+
+ /** Layout sub regions */
+ regions: {
+ RBusinessMetadataTableLayoutView: "#r_businessMetadataTableLayoutView",
+ REnumTableLayoutView: '#r_enumTableLayoutView',
+ RAdminTableLayoutView: '#r_adminTableLayoutView'
+ },
+
+ /** ui selector cache */
+ ui: {
+ tablist: '[data-id="tab-list"] li'
+ },
+ /** ui events hash */
+ events: function() {
+ var events = {};
+ events["click " + this.ui.tablist] = function(e) {
+ var tabValue = $(e.currentTarget).attr('role');
+ Utils.setUrl({
+ url: Utils.getUrlState.getQueryUrl().queyParams[0],
+ urlParams: { tabActive: tabValue || 'properties' },
+ mergeBrowserUrl: false,
+ trigger: false,
+ updateTabState: true
+ });
+
+ };
+
+ return events;
+ },
+ /**
+ * intialize a new AuditTableLayoutView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, _.pick(options, 'value', 'entityDefCollection', 'businessMetadataDefCollection', 'enumDefCollection', 'searchTableFilters'));
+
+ },
+ onShow: function() {
+ if (this.value && this.value.tabActive) {
+ this.$('.nav.nav-tabs').find('[role="' + this.value.tabActive + '"]').addClass('active').siblings().removeClass('active');
+ this.$('.tab-content').find('[role="' + this.value.tabActive + '"]').addClass('active').siblings().removeClass('active');
+ $("html, body").animate({ scrollTop: (this.$('.tab-content').offset().top + 1200) }, 1000);
+ }
+ },
+ bindEvents: function() {
+ this.renderEnumLayoutView();
+ this.renderAdminLayoutView();
+ },
+ onRender: function() {
+ this.renderBusinessMetadataLayoutView();
+ this.bindEvents();
+ },
+ renderBusinessMetadataLayoutView: function(obj) {
+ var that = this;
+ require(['views/business_metadata/BusinessMetadataTableLayoutView'], function(BusinessMetadataTableLayoutView) {
+ that.RBusinessMetadataTableLayoutView.show(new BusinessMetadataTableLayoutView({ businessMetadataDefCollection: that.businessMetadataDefCollection, entityDefCollection: that.entityDefCollection }));
+ });
+ },
+ renderEnumLayoutView: function(obj) {
+ var that = this;
+ require(["views/business_metadata/EnumCreateUpdateItemView"], function(EnumCreateUpdateItemView) {
+ var view = new EnumCreateUpdateItemView({
+ enumDefCollection: that.enumDefCollection,
+ businessMetadataDefCollection: that.businessMetadataDefCollection
+ });
+ that.REnumTableLayoutView.show(view);
+ });
+ },
+ renderAdminLayoutView: function(obj) {
+ var that = this;
+ require(["views/audit/AdminAuditTableLayoutView"], function(AdminAuditTableLayoutView) {
+ var view = new AdminAuditTableLayoutView({
+ searchTableFilters: that.searchTableFilters,
+ entityDefCollection: that.entityDefCollection,
+ enumDefCollection: that.enumDefCollection
+ });
+ that.RAdminTableLayoutView.show(view);
+ });
+ }
+ });
+ return AdministratorLayoutView;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/audit/AdminAuditTableLayoutView.js b/dashboardv2/public/js/views/audit/AdminAuditTableLayoutView.js
new file mode 100644
index 0000000..ba8a9f8
--- /dev/null
+++ b/dashboardv2/public/js/views/audit/AdminAuditTableLayoutView.js
@@ -0,0 +1,330 @@
+/**
+ * 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/AdminAuditTableLayoutView_tmpl',
+ 'collection/VEntityList',
+ 'utils/Utils',
+ 'utils/UrlLinks',
+ 'utils/CommonViewFunction'
+], function(require, Backbone, AdminAuditTableLayoutView_tmpl, VEntityList, Utils, UrlLinks, CommonViewFunction) {
+ 'use strict';
+
+ var AdminAuditTableLayoutView = Backbone.Marionette.LayoutView.extend(
+ /** @lends AuditTableLayoutView */
+ {
+ _viewName: 'AdminAuditTableLayoutView',
+
+ template: AdminAuditTableLayoutView_tmpl,
+
+ /** Layout sub regions */
+ regions: {
+ RAuditTableLayoutView: "#r_adminAuditTableLayoutView",
+ RQueryBuilderAdmin: "#r_attributeQueryBuilderAdmin"
+ },
+
+ /** ui selector cache */
+ ui: {
+ adminEntityClick: "[data-id='adminEntity']",
+ adminType: "[data-id='adminType']",
+ attrFilter: "[data-id='adminAttrFilter']",
+ adminRegion: "[data-id='adminRegion']",
+ attrApply: "[data-id='attrApply']",
+ showDefault: "[data-id='showDefault']",
+ attrClose: "[data-id='attrClose']"
+ },
+ /** ui events hash */
+ events: function() {
+ var events = {},
+ that = this;
+ events["click " + this.ui.adminEntityClick] = "onClickAdminEntity";
+ events["change " + this.ui.adminType] = "onClickAdminType";
+ events["click " + this.ui.attrFilter] = function(e) {
+ this.$('.fa-angle-right').toggleClass('fa-angle-down');
+ this.$('.attributeResultContainer').addClass("overlay");
+ this.$('.attribute-filter-container, .attr-filter-overlay').toggleClass('hide');
+ this.onClickAttrFilter();
+ };
+ events["click " + this.ui.attrClose] = function(e) {
+ that.closeAttributeModel();
+ };
+ events["click " + this.ui.attrApply] = function(e) {
+ that.okAttrFilterButton(e);
+ };
+ return events;
+ },
+ /**
+ * intialize a new AdminTableLayoutView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, _.pick(options, 'searchTableFilters', 'entityDefCollection', 'enumDefCollection'));
+ this.entityCollection = new VEntityList();
+ this.limit = 25;
+ this.entityCollection.url = UrlLinks.adminApiUrl();
+ this.entityCollection.modelAttrName = "events";
+ this.commonTableOptions = {
+ collection: this.entityCollection,
+ includeFilter: false,
+ includePagination: true,
+ includeFooterRecords: true,
+ includePageSize: true,
+ includeAtlasTableSorting: true,
+ includeTableLoader: true,
+ includeColumnManager: false,
+ gridOpts: {
+ className: "table table-hover backgrid table-quickMenu",
+ emptyText: 'No records found!'
+ },
+ columnOpts: {
+ opts: {
+ initialColumnsVisible: null,
+ saveState: false
+ },
+ visibilityControlOpts: {
+ buttonTemplate: _.template("<button class='btn btn-action btn-sm pull-right'>Columns <i class='fa fa-caret-down'></i></button>")
+ },
+ el: this.ui.colManager
+ },
+ filterOpts: {},
+ paginatorOpts: {}
+ };
+ this.isFilters = null;
+ },
+ onRender: function() {
+ var str = '<option>All</option><option>Purged</option>';
+ this.ui.adminType.html(str);
+ this.ui.adminType.select2({});
+ this.ui.adminRegion.hide();
+ this.getAdminCollection();
+ this.entityCollection.comparator = function(model) {
+ return -model.get('timestamp');
+ }
+ },
+ bindEvents: function() {},
+ closeAttributeModel: function() {
+ var that = this;
+ that.$('.attributeResultContainer').removeClass("overlay");
+ that.$('.fa-angle-right').toggleClass('fa-angle-down');
+ that.$('.attribute-filter-container, .attr-filter-overlay').toggleClass('hide');
+ },
+ getAttributes: function(options) {
+ var adminAttributes = [];
+ if (options.isFilter) {
+ _.each(options.isFilter, function(adminFilter) {
+ adminAttributes.push({
+ "attributeName": adminFilter.id,
+ "operator": adminFilter.operator,
+ "attributeValue": (adminFilter.type == "date" && options.isDateParsed) ? Date.parse(adminFilter.value).toString() : adminFilter.value
+ })
+ })
+ this.isFilters = null;
+ } else {
+ adminAttributes = [{
+ "attributeName": "userName",
+ "operator": "=",
+ "attributeValue": "admin"
+ }];
+ if (this.onlyPurged === true) {
+ adminAttributes.push({
+ "attributeName": "operation",
+ "operator": "=",
+ "attributeValue": "PURGE"
+ })
+ }
+ }
+ return adminAttributes;
+ },
+ onClickAttrFilter: function() {
+ var that = this;
+ this.ui.adminRegion.show();
+ require(['views/search/QueryBuilderView'], function(QueryBuilderView) {
+ that.RQueryBuilderAdmin.show(new QueryBuilderView({ adminAttrFilters: true, searchTableFilters: that.searchTableFilters, entityDefCollection: that.entityDefCollection, enumDefCollection: that.enumDefCollection }));
+ });
+ },
+ okAttrFilterButton: function(options) {
+ var that = this,
+ isFilterValidate = true,
+ queryBuilderRef = that.RQueryBuilderAdmin.currentView.ui.builder;
+ if (queryBuilderRef.data("queryBuilder")) {
+ var queryBuilder = queryBuilderRef.queryBuilder("getRules");
+ if (queryBuilder) {
+ that.isFilters = queryBuilder.rules;
+ } else {
+ isFilterValidate = false
+ }
+ }
+ if (isFilterValidate) {
+ that.closeAttributeModel();
+ that.getAdminCollection();
+ }
+ },
+ getAdminCollection: function() {
+ var that = this,
+ options = {
+ isDateParsed: true,
+ isFilter: this.isFilters
+ },
+ adminParam = {
+ condition: "AND",
+ criterion: that.getAttributes(options)
+ };
+ options.isDateParsed = false;
+ var auditQueryParam = {
+ condition: "AND",
+ criterion: that.getAttributes(options)
+ };
+ that.searchTableFilters["adminAttrFilters"] = CommonViewFunction.attributeFilter.generateUrl({ value: auditQueryParam, formatedDateToLong: true });
+ this.$('.fontLoader').show();
+ this.$('.tableOverlay').show();
+ $.extend(that.entityCollection.queryParams, { limit: this.limit, offset: 0, auditFilters: adminParam });
+ var apiObj = {
+ sort: false,
+ data: that.entityCollection.queryParams,
+ success: function(dataOrCollection, response) {
+ that.entityCollection.fullCollection.reset(dataOrCollection);
+ that.renderTableLayoutView();
+ that.$('.fontLoader').hide();
+ that.$('.tableOverlay').hide();
+ that.$('.auditTable').show();
+ },
+ silent: true,
+ reset: true
+ }
+ this.entityCollection.getAdminData(apiObj);
+ },
+ renderTableLayoutView: function() {
+ var that = this;
+ this.ui.showDefault.hide();
+ require(['utils/TableLayout'], function(TableLayout) {
+ var cols = new Backgrid.Columns(that.getAuditTableColumns());
+ that.RAuditTableLayoutView.show(new TableLayout(_.extend({}, that.commonTableOptions, {
+ columns: cols
+ })));
+ });
+ },
+ getAuditTableColumns: function() {
+ var that = this;
+ return this.entityCollection.constructor.getTableCols({
+ result: {
+ label: "",
+ cell: "html",
+ editable: false,
+ sortable: false,
+ cell: Backgrid.ExpandableCell,
+ fixWidth: "20",
+ accordion: false,
+ alwaysVisible: true,
+ expand: function(el, model) {
+ var adminValues = '<div class="col-sm-6">',
+ newColumn = '';
+ el.attr('colspan', '7');
+ if (model.attributes.params) {
+ var guids = model.attributes.result.replace('[', '').replace(']', '').split(',');
+ _.each(guids, function(adminGuid, index) {
+ if (index % 5 == 0 && index != 0) {
+ adminValues += '</div><div class="col-sm-6">';
+ }
+ adminValues += '<a class="blue-link" data-id="adminEntity" >' + adminGuid.trim() + '</a></br>';
+ })
+ adminValues += '</div>';
+
+ } else {
+ adminValues = '';
+ }
+ var adminText = '<div class="row"><div class="col-sm-12 attr-details admin-attr-details"><div class="col-sm-2">Purged Entities: </div><div class="col-sm-10">' + adminValues + '</div></div></div>';
+ $(el).append($('<div>').html(adminText));
+
+ }
+ },
+ userName: {
+ label: "Users",
+ cell: "html",
+ editable: false
+ },
+ operation: {
+ label: "Operation",
+ cell: "String",
+ editable: false
+ },
+ clientId: {
+ label: "Client ID",
+ cell: "String",
+ editable: false
+ },
+ resultCount: {
+ label: "Result Count",
+ cell: "String",
+ editable: false
+ },
+ startTime: {
+ label: "Start Time",
+ cell: "html",
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ return new Date(rawValue);
+ }
+ })
+ },
+ endTime: {
+ label: "End Time",
+ cell: "html",
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ return new Date(rawValue);
+ }
+ })
+ }
+ }, this.entityCollection);
+
+ },
+ onClickAdminType: function(e, value) {
+ this.onlyPurged = e.currentTarget.value === "Purged";
+ this.getAdminCollection();
+ },
+ onClickAdminEntity: function(e) {
+ var that = this;
+ require([
+ 'modules/Modal', 'views/audit/AuditTableLayoutView', 'views/audit/CreateAuditTableLayoutView',
+ ], function(Modal, AuditTableLayoutView, CreateAuditTableLayoutView) {
+ var obj = {
+ guid: $(e.target).text(),
+ },
+ modal = new Modal({
+ title: "Purged Entity Details: " + obj.guid,
+ content: new AuditTableLayoutView(obj),
+ mainClass: "modal-full-screen",
+ okCloses: true,
+ showFooter: false,
+ }).open();
+
+ modal.on('closeModal', function() {
+ $('.modal').css({ 'padding-right': '0px !important' });
+ modal.trigger('cancel');
+ });
+ modal.$el.on('click', 'td a', function() {
+ modal.trigger('cancel');
+ });
+ });
+ }
+ });
+ return AdminAuditTableLayoutView;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/audit/AuditTableLayoutView.js b/dashboardv2/public/js/views/audit/AuditTableLayoutView.js
index d186007..65b8818 100644
--- a/dashboardv2/public/js/views/audit/AuditTableLayoutView.js
+++ b/dashboardv2/public/js/views/audit/AuditTableLayoutView.js
@@ -179,6 +179,32 @@
getAuditTableColumns: function() {
var that = this;
return this.entityCollection.constructor.getTableCols({
+
+ tool: {
+ label: "",
+ cell: "html",
+ editable: false,
+ sortable: false,
+ fixWidth: "20",
+ cell: Backgrid.ExpandableCell,
+ accordion: false,
+ expand: function(el, model) {
+ el.attr('colspan', '4');
+ require([
+ 'views/audit/CreateAuditTableLayoutView',
+ ], function(CreateAuditTableLayoutView) {
+
+ that.action = model.get('action');
+ // $(el.target).attr('disabled', true);
+ var eventModel = that.entityCollection.fullCollection.findWhere({ 'eventKey': model.get('eventKey') }).toJSON(),
+ collectionModel = new that.entityCollection.model(eventModel),
+ view = new CreateAuditTableLayoutView({ guid: that.guid, entityModel: collectionModel, action: that.action, entity: that.entity, entityName: that.entityName, attributeDefs: that.attributeDefs });
+ view.render();
+ $(el).append($('<div>').html(view.$el));
+ });
+
+ }
+ },
user: {
label: "Users",
cell: "html",
@@ -207,19 +233,7 @@
}
}
})
- },
- tool: {
- 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-id="auditCreate" data-action="' + Enums.auditAction[model.get('action')] + '" data-modalId="' + model.get('eventKey') + '">Detail</div>';
- }
- })
- },
-
+ }
}, this.entityCollection);
},
diff --git a/dashboardv2/public/js/views/audit/CreateAuditTableLayoutView.js b/dashboardv2/public/js/views/audit/CreateAuditTableLayoutView.js
index f7673ce..a820616 100644
--- a/dashboardv2/public/js/views/audit/CreateAuditTableLayoutView.js
+++ b/dashboardv2/public/js/views/audit/CreateAuditTableLayoutView.js
@@ -124,11 +124,7 @@
relationshipAttributes = parseDetailsObject.relationshipAttributes;
if (attributesDetails) {
that.ui.attributeDetails.removeClass('hide');
- if (that.action.includes("Classification") || that.action.includes("Business Attribute") != -1) {
- that.ui.panelAttrHeading.html("Properties ");
- } else {
- that.ui.panelAttrHeading.html("Technical properties ");
- }
+ that.action.indexOf("Classification") === -1 ? that.ui.panelAttrHeading.html("Technical properties ") : that.ui.panelAttrHeading.html("Properties ");
var attrTable = that.createTableWithValues(attributesDetails);
that.ui.attributeCard.html(
attrTable);
@@ -178,4 +174,4 @@
}
});
return CreateAuditTableLayoutView;
-});
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttrTableLayoutView.js b/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttrTableLayoutView.js
new file mode 100644
index 0000000..12cc710
--- /dev/null
+++ b/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttrTableLayoutView.js
@@ -0,0 +1,246 @@
+/**
+ * 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/business_metadata/BusinessMetadataAttrTableLayoutView_tmpl',
+ 'collection/VEntityList'
+], function(require, Backbone, BusinessMetadataAttrTableLayoutView_tmpl, VEntityList) {
+ 'use strict';
+
+ var BusinessMetadataAttrTableLayoutView = Backbone.Marionette.LayoutView.extend(
+ /** @lends BusinessMetadataAttrTableLayoutView */
+ {
+ _viewName: 'BusinessMetadataAttrTableLayoutView',
+
+ template: BusinessMetadataAttrTableLayoutView_tmpl,
+
+ /** Layout sub regions */
+ regions: {
+ RBusinessMetadataAttrTableLayoutView: "#r_businessMetadataAttrTableLayoutView",
+ RModal: "#r_modal"
+ },
+
+ /** ui selector cache */
+ ui: {
+ attributeEdit: "[data-id='attributeEdit']",
+ addAttribute: '[data-id="addAttribute"]',
+ businessMetadataAttrPage: "[data-id='businessMetadataAttrPage']",
+ businessMetadataAttrPageTitle: "[data-id='businessMetadataAttrPageTitle']",
+ businessMetadataDetailPage: "[data-id='businessMetadataDetailPage']",
+ },
+ /** ui events hash */
+ events: function() {
+ var events = {};
+ events["click " + this.ui.attributeEdit] = "onEditAttr";
+ events["click " + this.ui.addAttribute] = "onEditAttr";
+ return events;
+ },
+ /**
+ * intialize a new BusinessMetadataAttrTableLayoutView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, _.pick(options, 'guid', 'model', 'typeHeaders', 'businessMetadataDefCollection', 'entityDefCollection'));
+ this.businessMetadataAttr = new VEntityList(this.model.get("attributeDefs") || []);
+ this.commonTableOptions = {
+ collection: this.businessMetadataAttr,
+ includeFilter: false,
+ includePagination: false,
+ includePageSize: false,
+ includeAtlasTableSorting: true,
+ includeFooterRecords: false,
+ gridOpts: {
+ className: "table table-hover backgrid table-quickMenu",
+ emptyText: 'No records found!'
+ },
+ filterOpts: {},
+ paginatorOpts: {}
+ };
+ this.showDetails = true;
+ },
+ onRender: function() {
+ this.renderTableLayoutView();
+ this.toggleBusinessMetadataDetailsAttrView();
+ },
+ bindEvents: function() {},
+ toggleBusinessMetadataDetailsAttrView: function() {
+ var that = this;
+ if (that.showDetails) {
+ that.ui.businessMetadataAttrPage.hide();
+ that.ui.businessMetadataDetailPage.show();
+ } else {
+ that.ui.businessMetadataAttrPage.show();
+ that.ui.businessMetadataDetailPage.hide();
+ }
+ },
+ onEditAttr: function(e) {
+ var that = this,
+ isAttrEdit = false,
+ selectedBusinessMetadata = that.model,
+ attrributes = selectedBusinessMetadata ? selectedBusinessMetadata.get('attributeDefs') : null,
+ attrName = e.target.dataset.name ? e.target.dataset.name : null,
+ attrDetails = { name: attrName };
+ if (e.target.dataset.action == 'attributeEdit') {
+ isAttrEdit = true
+ }
+ if (selectedBusinessMetadata) {
+ that.newAttr = isAttrEdit ? false : true;
+ _.each(attrributes, function(attrObj) {
+ if (attrObj.name === attrName) {
+ attrDetails = $.extend(true, {}, attrObj);
+ if (attrObj.typeName.includes('array')) {
+ attrDetails.typeName = attrObj.typeName.replace("array<", "").replace(">", "");
+ attrDetails.multiValued = true;
+ }
+ }
+ });
+ this.showDetails = false;
+ that.toggleBusinessMetadataDetailsAttrView();
+ require(["views/business_metadata/CreateBusinessMetadataLayoutView"], function(CreateBusinessMetadataLayoutView) {
+ that.view = new CreateBusinessMetadataLayoutView({
+ onEditCallback: function() {
+ enumDefCollection.fetch({ reset: true });
+ that.businessMetadataAttr.reset(that.model.get("attributeDefs"));
+ },
+ onUpdateBusinessMetadata: function(fetch) {
+ that.showDetails = true;
+ that.toggleBusinessMetadataDetailsAttrView();
+ if (fetch) {
+ that.entityDefCollection.fetch({ silent: true });
+ }
+ },
+ parent: that.$el,
+ businessMetadataDefCollection: that.businessMetadataDefCollection,
+ enumDefCollection: enumDefCollection,
+ isAttrEdit: isAttrEdit,
+ attrDetails: attrDetails,
+ typeHeaders: typeHeaders,
+ selectedBusinessMetadata: that.model,
+ guid: that.guid,
+ isNewAttr: that.newAttr
+ });
+ if (isAttrEdit) {
+ that.ui.businessMetadataAttrPageTitle.text("Update Attribute of: " + selectedBusinessMetadata.get('name'));
+ } else {
+ that.ui.businessMetadataAttrPageTitle.text("Add Business Metadata Attribute for: " + selectedBusinessMetadata.get('name'));
+ }
+ that.RModal.show(that.view);
+ });
+ }
+
+ },
+ renderTableLayoutView: function() {
+ var that = this;
+ require(['utils/TableLayout'], function(TableLayout) {
+ var cols = new Backgrid.Columns(that.getBusinessMetadataTableColumns());
+ that.RBusinessMetadataAttrTableLayoutView.show(new TableLayout(_.extend({}, that.commonTableOptions, {
+ columns: cols
+ })));
+ });
+ },
+ getBusinessMetadataTableColumns: function() {
+ var that = this;
+ return this.businessMetadataAttr.constructor.getTableCols({
+ name: {
+ label: "Attribute Name",
+ cell: "html",
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ return _.escape(model.get('name'));
+ }
+ })
+ },
+ typeName: {
+ label: "Type Name",
+ cell: "html",
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ return _.escape(model.get('typeName'));
+ }
+ })
+ },
+ searchWeight: {
+ label: "Search Weight",
+ cell: "String",
+ editable: false
+ },
+ enableMultipleValue: {
+ label: "Enable Multivalues",
+ cell: "html",
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var enableMultipleValue = '';
+ if (model.get('typeName').indexOf('array<') > -1) {
+ enableMultipleValue = 'checked';
+ }
+ return '<input type="checkbox" class="form-check-input multi-value-select" data-id="multiValueSelectStatus" ' + enableMultipleValue + ' disabled="disabled">';
+ }
+ })
+ },
+ maxStrLength: {
+ label: "Max Length",
+ cell: "html",
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var maxString = "NA";
+ if (model.get('typeName').indexOf('string') > -1) {
+ maxString = model.get('options').maxStrLength || maxString;
+ }
+ return maxString;
+ }
+ })
+ },
+ options: {
+ label: "Entity Type(s)",
+ cell: "html",
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var options = model.get('options')
+ if (options && options.applicableEntityTypes) {
+ var applicableEntityTypes = '',
+ attrEntityTypes = JSON.parse(options.applicableEntityTypes);
+ _.each(attrEntityTypes, function(values) {
+ applicableEntityTypes += '<label class="btn btn-action btn-sm btn-blue no-pointer">' + values + '</label>';
+ });
+ return applicableEntityTypes;
+ }
+ }
+ })
+ },
+ tool: {
+ label: "Action",
+ cell: "html",
+ editable: false,
+ sortable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ return '<div class="btn btn-action btn-sm" data-id="attributeEdit" data-action="attributeEdit" data-name="' + model.get('name') + '">Edit</div>';
+ }
+ })
+ }
+ }, this.businessMetadataAttr);
+ }
+ });
+ return BusinessMetadataAttrTableLayoutView;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttributeItemView.js b/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttributeItemView.js
new file mode 100644
index 0000000..85c64d0
--- /dev/null
+++ b/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttributeItemView.js
@@ -0,0 +1,309 @@
+/*
+ * 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/business_metadata/BusinessMetadataAttributeItemView_tmpl'
+], function(require, Backbone, BusinessMetadataAttributeItemViewTmpl) {
+ 'use strict';
+
+ return Backbone.Marionette.ItemView.extend(
+ /** @lends GlobalExclusionListView */
+ {
+
+ template: BusinessMetadataAttributeItemViewTmpl,
+ templateHelpers: function() {
+ return {
+ modalID: this.viewId
+ };
+ },
+
+ /** Layout sub regions */
+ regions: {},
+
+ /** ui selector cache */
+ ui: {
+ attributeInput: "[data-id='attributeInput']",
+ close: "[data-id='close']",
+ dataTypeSelector: "[data-id='dataTypeSelector']",
+ searchWeightSelector: "[data-id='searchWeightSelector']",
+ entityTypeSelector: "[data-id='entityTypeSelector']",
+ enumTypeSelectorContainer: "[data-id='enumTypeSelectorContainer']",
+ enumTypeSelector: "[data-id='enumTypeSelector']",
+ enumValueSelectorContainer: "[data-id='enumValueSelectorContainer']",
+ enumValueSelector: "[data-id='enumValueSelector']",
+ multiValueSelect: "[data-id='multiValueSelect']",
+ multiValueSelectStatus: "[data-id='multiValueSelectStatus']",
+ stringLengthContainer: "[data-id='stringLengthContainer']",
+ stringLengthValue: "[data-id='stringLength']",
+ createNewEnum: "[data-id='createNewEnum']"
+ },
+ /** ui events hash */
+ events: function() {
+ var events = {};
+ events["keyup " + this.ui.attributeInput] = function(e) {
+ this.model.set({ "name": e.target.value.trim() });
+ };
+ events["change " + this.ui.searchWeightSelector] = function(e) {
+ this.model.set({ "searchWeight": e.target.value.trim() });
+ };
+ events["change " + this.ui.dataTypeSelector] = function(e) {
+ var obj = { options: this.model.get('options') || {} };
+ delete obj.enumValues;
+ delete obj.options.maxStrLength;
+ if (e.target.value.trim() === 'enumeration' || e.target.value.trim() === 'Enumeration') {
+ this.ui.enumTypeSelectorContainer.show();
+ this.ui.enumTypeSelector.show();
+ this.emumTypeSelectDisplay();
+ this.ui.stringLengthContainer.hide();
+ this.ui.stringLengthValue.hide();
+ } else {
+ obj.typeName = e.target.value.trim();
+ if (e.target.value.trim() === 'string' || e.target.value.trim() === 'String') {
+ this.ui.stringLengthContainer.show();
+ this.ui.stringLengthValue.show();
+ this.ui.enumTypeSelectorContainer.hide();
+ this.ui.enumTypeSelector.hide();
+ this.ui.enumValueSelectorContainer.hide();
+ obj.options["maxStrLength"] = e.target.value.trim();
+ } else {
+ this.ui.enumTypeSelectorContainer.hide();
+ this.ui.enumTypeSelector.hide();
+ this.ui.enumValueSelectorContainer.hide();
+ this.ui.stringLengthContainer.hide();
+ this.ui.stringLengthValue.hide();
+ }
+ }
+ this.model.set(obj);
+ if (e.target.value.trim() != 'enumeration') {
+ this.ui.multiValueSelectStatus.trigger('change');
+ }
+ };
+ events["change " + this.ui.enumTypeSelector] = function(e) {
+ this.model.set({ "enumValues": e.target.value.trim() });
+ };
+ events["change " + this.ui.stringLengthContainer] = function(e) {
+ var options = this.model.get('options') || {};
+ if (this.ui.dataTypeSelector.val() == 'string') {
+ options["maxStrLength"] = e.target.value.trim();
+ }
+ this.model.set({ "options": options });
+
+ };
+ events["change " + this.ui.enumTypeSelector] = function(e) {
+ var emumValue = this.ui.enumTypeSelector.select2('data')[0] ? this.ui.enumTypeSelector.select2('data')[0].text : this.ui.enumTypeSelector.val();
+
+ this.model.set({ "typeName": emumValue });
+ if (this.model.get("multiValueSelect")) {
+ this.model.set({ "typeName": "array<" + emumValue + ">" });
+ }
+ if (emumValue == '' || emumValue == null) {
+ this.ui.enumValueSelectorContainer.hide();
+ } else {
+ this.ui.enumValueSelectorContainer.show();
+ this.showEnumValues(_.escape(emumValue));
+ }
+ };
+ events["change " + this.ui.enumValueSelector] = function(e) {
+ this.model.set({ "enumValues": this.ui.enumValueSelector.val() });
+ };
+ events["change " + this.ui.multiValueSelectStatus] = function(e) {
+ this.model.set({ "multiValueSelect": e.target.checked });
+ var typename = this.model.get('typeName');
+ if (e.target.checked) {
+ typename = "array<" + typename + ">";
+ } else {
+ typename = typename.replace('array<', '').replace('>', '');
+ }
+ this.model.set({ "typeName": typename });
+ };
+ events["change " + this.ui.entityTypeSelector] = function(e) {
+ var options = this.model.get('options') || {};
+ options.applicableEntityTypes = JSON.stringify(this.ui.entityTypeSelector.val());
+ this.model.set({ "options": options });
+ }
+ events["click " + this.ui.close] = 'onCloseButton';
+ events["click " + this.ui.createNewEnum] = 'onCreateUpdateEnum';
+ return events;
+ },
+
+ /**
+ * intialize a new GlobalExclusionComponentView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, _.pick(options, "typeHeaders", "businessMetadataDefCollection", "enumDefCollection", "isAttrEdit", "viewId", "collection"));
+ this.viewId = options.model ? options.model.cid : this.viewId;
+ },
+ onRender: function() {
+ var that = this,
+ entitytypes = '',
+ enumTypes = [],
+ searchWeightValue = '5',
+ stringLengthValue = '50',
+ applicableEntityType = '';
+ this.typeHeaders.fullCollection.each(function(model) {
+ if (model.toJSON().category == "ENTITY") {
+ that.ui.entityTypeSelector.append("<option>" + model.get('name') + "</option>");
+ entitytypes += '<option value="' + (model.get('name')) + '" data-name="' + (model.get('name')) + '">' + model.get('name') + '</option>';
+ }
+ });
+ this.ui.entityTypeSelector.select2({
+ placeholder: "Select Entity type",
+ allowClear: true,
+ multiple: true,
+ selectionAdapter: $.fn.select2.amd.require("TagHideDeleteButtonAdapter")
+ });
+ this.ui.entityTypeSelector.html(entitytypes);
+ this.ui.entityTypeSelector.on('select2:open', function(e) { // to make selected option disable in dropdown added remove-from-list class
+ $('.select2-dropdown--below').addClass('remove-from-list');
+ });
+ if (this.model.get("searchWeight")) {
+ searchWeightValue = this.model.get("searchWeight") === -1 ? 0 : this.model.get("searchWeight");
+ }
+ if (this.model.get("options")) {
+ stringLengthValue = this.model.get("options").maxStrLength || '50';
+ applicableEntityType = this.model.get("options").applicableEntityTypes ? JSON.parse(this.model.get("options").applicableEntityTypes) : null;
+ }
+ this.ui.stringLengthValue.val(stringLengthValue).trigger('change'); //default length for string is 50
+ this.ui.searchWeightSelector.val(searchWeightValue).trigger('change');
+ this.ui.enumValueSelector.attr("disabled", "false"); // cannot edit the values
+ this.emumTypeSelectDisplay();
+ this.ui.enumTypeSelectorContainer.hide();
+ this.ui.enumTypeSelector.hide();
+ this.ui.enumValueSelectorContainer.hide();
+ if (this.isAttrEdit) {
+ var typeName = this.model.get("typeName");
+ this.ui.close.hide();
+ this.ui.createNewEnum.hide(); // cannot add new businessMetadata on edit view
+ this.ui.attributeInput.val(this.model.get("name"));
+ this.ui.attributeInput.attr("disabled", "false");
+ this.ui.dataTypeSelector.attr("disabled", "false");
+ this.ui.dataTypeSelector.attr("disabled", "false");
+ this.ui.multiValueSelect.hide();
+ this.ui.dataTypeSelector.val(typeName);
+ if (typeName == "string") {
+ this.ui.stringLengthContainer.show();
+ this.ui.stringLengthValue.show();
+ } else {
+ this.ui.stringLengthContainer.hide();
+ this.ui.stringLengthValue.hide();
+ }
+ if (applicableEntityType) {
+ _.each(applicableEntityType, function(valName) {
+ that.ui.entityTypeSelector.find('option').each(function(o) {
+ var $el = $(this)
+ if ($el.data("name") === valName) {
+ $el.attr("data-allowremove", "false");
+ }
+ })
+ });
+ }
+ this.ui.entityTypeSelector.val(applicableEntityType).trigger('change');
+ if (typeName != "string" && typeName != "boolean" && typeName != "byte" && typeName != "short" && typeName != "int" && typeName != "float" && typeName != "double" && typeName != "long" && typeName != "date") {
+ this.ui.enumTypeSelector.attr("disabled", "false");
+ this.ui.dataTypeSelector.val("enumeration").trigger('change');
+ this.ui.enumTypeSelector.val(typeName).trigger('change');
+ }
+ if (this.model.get("multiValued")) {
+ this.ui.multiValueSelect.show();
+ $(this.ui.multiValueSelectStatus).prop('checked', true).trigger('change');
+ this.ui.multiValueSelectStatus.attr("disabled", "false");
+ }
+ }
+ },
+ showEnumValues: function(enumName) {
+ var enumValues = '',
+ selectedValues = [],
+ selectedEnum = this.enumDefCollection.fullCollection.findWhere({ name: enumName }),
+ selectedEnumValues = selectedEnum ? selectedEnum.get('elementDefs') : null,
+ savedValues = [];
+ _.each(selectedEnumValues, function(enumVal, index) {
+ selectedValues.push(_.unescape(enumVal.value));
+ enumValues += "<option>" + enumVal.value + "</option>";
+ });
+ this.ui.enumValueSelector.empty();
+ this.ui.enumValueSelector.append(enumValues);
+ this.ui.enumValueSelector.val(selectedValues);
+ this.ui.enumValueSelector.select2({
+ placeholder: "Select Enum value",
+ allowClear: false,
+ tags: false,
+ multiple: true
+ });
+ this.model.set({ "enumValues": this.ui.enumValueSelector.val() });
+ },
+ emumTypeSelectDisplay: function() {
+ var enumTypes = '';
+ this.enumDefCollection.fullCollection.each(function(model, index) {
+ enumTypes += "<option>" + _.escape(model.get('name')) + "</option>";
+ });
+ this.ui.enumTypeSelector.empty();
+ this.ui.enumTypeSelector.append(enumTypes);
+ this.ui.enumTypeSelector.val('');
+ this.ui.enumTypeSelector.select2({
+ placeholder: "Select Enum name",
+ tags: false,
+ allowClear: true,
+ multiple: false
+ });
+ },
+ onCreateUpdateEnum: function(e) {
+ var that = this;
+ require(["views/business_metadata/EnumCreateUpdateItemView", "modules/Modal"], function(EnumCreateUpdateItemView, Modal) {
+ var view = new EnumCreateUpdateItemView({
+ onUpdateEnum: function() {
+ that.ui.enumValueSelectorContainer.hide();
+ that.emumTypeSelectDisplay();
+ that.ui.enumValueSelector.empty();
+ },
+ closeModal: function() {
+ modal.trigger("cancel");
+ that.enumDefCollection.fetch({
+ success: function() {
+ that.ui.enumTypeSelector.val(that.model.get('typeName')).trigger('change');
+ }
+ });
+ },
+ enumDefCollection: that.enumDefCollection,
+ businessMetadataDefCollection: that.businessMetadataDefCollection
+ }),
+ modal = new Modal({
+ title: "Create/ Update Enum",
+ content: view,
+ cancelText: "Cancel",
+ okCloses: false,
+ okText: "Update",
+ allowCancel: true,
+ showFooter: false
+ }).open();
+ modal.on('closeModal', function() {
+ modal.trigger('cancel');
+ });
+ });
+ },
+ onCloseButton: function() {
+ var tagName = this.$el.find('[data-id="tagName"]').val();
+ if (this.collection.models.length > 0) {
+ this.model.destroy();
+ }
+ if (this.collection.models.length == 0 && tagName != "") {
+ this.$el.parent().next().find('button.ok').removeAttr("disabled");
+ }
+ }
+ });
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/business_metadata/BusinessMetadataContainerLayoutView.js b/dashboardv2/public/js/views/business_metadata/BusinessMetadataContainerLayoutView.js
new file mode 100644
index 0000000..6ae97f9
--- /dev/null
+++ b/dashboardv2/public/js/views/business_metadata/BusinessMetadataContainerLayoutView.js
@@ -0,0 +1,93 @@
+/**
+ * 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/business_metadata/BusinessMetadataContainerLayoutView_tmpl"
+], function(require, Backbone, BusinessMetadataContainerLayoutViewTmpl) {
+ "use strict";
+
+ var BusinessMetadataContainerLayoutView = Backbone.Marionette.LayoutView.extend(
+ /** @lends BusinessMetadataContainerLayoutView */
+ {
+ _viewName: "BusinessMetadataContainerLayoutView",
+
+ template: BusinessMetadataContainerLayoutViewTmpl,
+
+ /** Layout sub regions */
+ regions: {
+ RBusinessMetadataDetailContainer: "#r_businessMetadataDetailContainer",
+ RBusinessMetadataAttrContainer: "#r_businessMetadataAttrContainer"
+ },
+
+ /** ui selector cache */
+ ui: {},
+ /** ui events hash */
+ events: function() {},
+ /**
+ * intialize a new TagLayoutView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, options);
+ },
+ bindEvents: function() {},
+ onRender: function() {
+ this.updateView();
+ },
+ updateView: function() {
+ this.model = this.businessMetadataDefCollection.fullCollection.findWhere({ guid: this.guid });
+ this.renderBusinessMetadataDetailLayoutView();
+ this.renderBusinessMetadataAttrLayoutView();
+ },
+ renderBusinessMetadataDetailLayoutView: function() {
+ var that = this;
+ require(["views/business_metadata/BusinessMetadataDetailLayoutView"], function(BusinessMetadataDetailLayoutView) {
+ if (that.isDestroyed) {
+ return;
+ }
+ that.RBusinessMetadataDetailContainer.show(new BusinessMetadataDetailLayoutView({
+ businessMetadataDefCollection: that.businessMetadataDefCollection,
+ guid: that.guid,
+ model: that.model,
+ enumDefCollection: that.enumDefCollection,
+ typeHeaders: that.typeHeaders
+ }));
+ });
+ },
+ renderBusinessMetadataAttrLayoutView: function() {
+ var that = this;
+ require(["views/business_metadata/BusinessMetadataAttrTableLayoutView"], function(BusinessMetadataAttrTableLayoutView) {
+ if (that.isDestroyed) {
+ return;
+ }
+ that.RBusinessMetadataAttrContainer.show(new BusinessMetadataAttrTableLayoutView({
+ businessMetadataDefCollection: that.businessMetadataDefCollection,
+ model: that.model,
+ guid: that.guid,
+ typeHeaders: that.typeHeaders,
+ enumDefCollection: that.enumDefCollection,
+ entityDefCollection: that.entityDefCollection
+ }));
+ });
+ }
+ }
+ );
+ return BusinessMetadataContainerLayoutView;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js b/dashboardv2/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
new file mode 100644
index 0000000..02cc503
--- /dev/null
+++ b/dashboardv2/public/js/views/business_metadata/BusinessMetadataDetailLayoutView.js
@@ -0,0 +1,66 @@
+/**
+ * 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/business_metadata/BusinessMetadataDetailLayoutView_tmpl',
+ 'utils/Utils',
+], function(require, Backbone, BusinessMetadataDetailLayoutViewTmpl, Utils) {
+ 'use strict';
+
+ var BusinessMetadataDetailLayoutView = Backbone.Marionette.LayoutView.extend(
+ /** @lends BusinessMetadataDetailLayoutView */
+ {
+ template: BusinessMetadataDetailLayoutViewTmpl,
+ /** Layout sub regions */
+ regions: {},
+ /** ui selector cache */
+ ui: {
+ title: '[data-id="title"]',
+ description: '[data-id="description"]'
+ },
+ /** ui events hash */
+ events: function() {
+ var events = {};
+ return events;
+ },
+ /**
+ * intialize a new BusinessMetadataDetailLayoutView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, _.pick(options, 'model'));
+ $('body').addClass("detail-page");
+ },
+ onRender: function() {
+ this.renderDetail();
+ },
+ renderDetail: function() {
+ this.ui.title.html('<span>' + this.model.get('name') + '</span>');
+ if (this.model.get('description')) {
+ this.ui.description.text((this.model.get('description')));
+ }
+ },
+ onDestroy: function() {
+ if (!Utils.getUrlState.isBSDetail()) {
+ $('body').removeClass("detail-page");
+ }
+ }
+ });
+ return BusinessMetadataDetailLayoutView;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js b/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
new file mode 100644
index 0000000..329b5bb
--- /dev/null
+++ b/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js
@@ -0,0 +1,405 @@
+/**
+ * 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/business_metadata/BusinessMetadataTableLayoutView_tmpl',
+ 'utils/Utils',
+ 'utils/Messages'
+], function(require, Backbone, BusinessMetadataTableLayoutView_tmpl, Utils, Messages) {
+ 'use strict';
+
+ var BusinessMetadataTableLayoutView = Backbone.Marionette.LayoutView.extend(
+ /** @lends BusinessMetadataTableLayoutView */
+ {
+ _viewName: 'BusinessMetadataTableLayoutView',
+
+ template: BusinessMetadataTableLayoutView_tmpl,
+
+ /** Layout sub regions */
+ regions: {
+ RBusinessMetadataTableLayoutView: "#r_businessMetadataTableLayoutView",
+ RModal: "#r_modal"
+ },
+
+ /** ui selector cache */
+ ui: {
+ businessMetadataAttrPage: "[data-id='businessMetadataAttrPage']",
+ businessMetadataAttrPageTitle: "[data-id='businessMetadataAttrPageTitle']",
+ businessMetadataDetailPage: "[data-id='businessMetadataDetailPage']",
+ createBusinessMetadata: "[data-id='createBusinessMetadata']",
+ attributeEdit: "[data-id='attributeEdit']",
+ addAttribute: '[data-id="addAttribute"]',
+ businessMetadataAttrPageOk: '[data-id="businessMetadataAttrPageOk"]',
+ colManager: "[data-id='colManager']",
+ deleteBusinessMetadata: '[data-id="deleteBusinessMetadata"]'
+ },
+ /** ui events hash */
+ events: function() {
+ var events = {},
+ that = this;
+ events["click " + this.ui.createBusinessMetadata] = "onClickCreateBusinessMetadata";
+ events["click " + this.ui.addAttribute] = "onEditAttr";
+ events["click " + this.ui.attributeEdit] = "onEditAttr";
+ events["click " + this.ui.deleteBusinessMetadata] = function(e) {
+ that.guid = e.target.dataset.guid;
+ that.deleteBusinessMetadataElement();
+ };
+ return events;
+ },
+ /**
+ * intialize a new BusinessMetadataTableLayoutView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, _.pick(options, 'guid', 'entity', 'entityName', 'attributeDefs', 'typeHeaders', 'businessMetadataDefCollection', 'entityDefCollection', 'businessMetadataAttr', 'selectedBusinessMetadata'));
+ this.limit = 10;
+ this.newAttr = false;
+ this.commonTableOptions = {
+ collection: this.businessMetadataDefCollection,
+ includeFilter: false,
+ includePagination: true,
+ includeFooterRecords: true,
+ includePageSize: true,
+ includeGotoPage: true,
+ includeAtlasTableSorting: true,
+ includeTableLoader: true,
+ includeColumnManager: true,
+ gridOpts: {
+ className: "table table-hover backgrid table-quickMenu",
+ emptyText: 'No records found!'
+ },
+ columnOpts: {
+ opts: {
+ initialColumnsVisible: null,
+ saveState: false
+ },
+ visibilityControlOpts: {
+ buttonTemplate: _.template("<button class='btn btn-action btn-sm pull-right'>Columns <i class='fa fa-caret-down'></i></button>")
+ },
+ el: this.ui.colManager
+ },
+ filterOpts: {},
+ paginatorOpts: {}
+ };
+ this.guid = null;
+ this.showDetails = true; // toggle between sttribute page and detail page
+ },
+ onRender: function() {
+ this.toggleBusinessMetadataDetailsAttrView();
+ $.extend(this.businessMetadataDefCollection.queryParams, { count: this.limit });
+ this.businessMetadataDefCollection.fullCollection.sort({ silent: true });
+ this.renderTableLayoutView();
+ this.$('.tableOverlay').hide();
+ this.$('.auditTable').show(); // Only for first time table show because we never hide after first render.
+ this.businessMetadataDefCollection.comparator = function(model) {
+ return -model.get('timestamp');
+ }
+ },
+ toggleBusinessMetadataDetailsAttrView: function() {
+ var that = this;
+ if (that.showDetails) {
+ that.ui.businessMetadataAttrPage.hide();
+ that.ui.businessMetadataDetailPage.show();
+ } else {
+ that.ui.businessMetadataAttrPage.show();
+ that.ui.businessMetadataDetailPage.hide();
+ }
+ },
+ bindEvents: function() {},
+ loaderStatus: function(isActive) {
+ var that = this;
+ if (isActive) {
+ that.$('.businessMetadata-attr-tableOverlay').show();
+ that.$('.business-metadata-attr-fontLoader').show();
+ } else {
+ that.$('.businessMetadata-attr-tableOverlay').hide();
+ that.$('.business-metadata-attr-fontLoader').hide();
+ }
+ },
+ onEditAttr: function(e) {
+ var that = this,
+ isAttrEdit = e.currentTarget.dataset && e.currentTarget.dataset.id === 'attributeEdit' ? true : false,
+ guid = e.currentTarget.dataset && e.currentTarget.dataset.guid ? e.currentTarget.dataset.guid : null,
+ selectedBusinessMetadata = that.businessMetadataDefCollection.fullCollection.findWhere({ guid: guid }),
+ attrributes = selectedBusinessMetadata ? selectedBusinessMetadata.get('attributeDefs') : null,
+ attrName = e.currentTarget.dataset.name ? e.currentTarget.dataset.name : null,
+ attrDetails = { name: attrName };
+ if (selectedBusinessMetadata) {
+ that.ui.businessMetadataAttrPageOk.text("Save");
+ that.newAttr = e.currentTarget && e.currentTarget.dataset.action === "createAttr" ? true : false;
+ that.guid = guid;
+ _.each(attrributes, function(attrObj) {
+ if (attrObj.name === attrName) {
+ attrDetails = $.extend(true, {}, attrObj);
+ if (attrObj.typeName.includes('array')) {
+ attrDetails.typeName = attrObj.typeName.replace("array<", "").replace(">", "");
+ attrDetails.multiValued = true;
+ }
+ }
+ });
+
+ that.showDetails = false;
+ that.toggleBusinessMetadataDetailsAttrView();
+ that.ui.businessMetadataAttrPageOk.attr('data-action', e.currentTarget.dataset.id);
+ require(["views/business_metadata/CreateBusinessMetadataLayoutView"], function(CreateBusinessMetadataLayoutView) {
+ that.view = new CreateBusinessMetadataLayoutView({
+ onEditCallback: function() {
+ that.businessMetadataDefCollection.fullCollection.sort({ silent: true });
+ that.renderTableLayoutView();
+ },
+ onUpdateBusinessMetadata: function(fetch) {
+ that.showDetails = true;
+ that.toggleBusinessMetadataDetailsAttrView();
+ if (fetch) {
+ enumDefCollection.fetch({ reset: true });
+ that.entityDefCollection.fetch({ silent: true });
+ }
+ },
+ parent: that.$el,
+ businessMetadataDefCollection: that.businessMetadataDefCollection,
+ enumDefCollection: enumDefCollection,
+ isAttrEdit: isAttrEdit,
+ typeHeaders: typeHeaders,
+ attrDetails: attrDetails,
+ selectedBusinessMetadata: selectedBusinessMetadata,
+ guid: that.guid,
+ isNewAttr: that.newAttr
+ });
+ if (isAttrEdit) {
+ that.ui.businessMetadataAttrPageTitle.text("Update Attribute of: " + selectedBusinessMetadata.get('name'));
+ } else {
+ that.ui.businessMetadataAttrPageTitle.text("Add Business Metadata Attribute for: " + selectedBusinessMetadata.get('name'));
+ }
+
+ that.RModal.show(that.view);
+ });
+ }
+ },
+ onClickCreateBusinessMetadata: function(e) {
+ var that = this,
+ isNewBusinessMetadata = true;
+ that.showDetails = false;
+ that.ui.businessMetadataAttrPageOk.text("Create");
+ that.ui.businessMetadataAttrPageOk.attr('data-action', 'createBusinessMetadata');
+ that.ui.businessMetadataAttrPageTitle.text("Create Business Metadata");
+ that.toggleBusinessMetadataDetailsAttrView();
+ require(["views/business_metadata/CreateBusinessMetadataLayoutView"], function(CreateBusinessMetadataLayoutView) {
+ that.view = new CreateBusinessMetadataLayoutView({
+ onUpdateBusinessMetadata: function(fetch) {
+ that.showDetails = true;
+ that.toggleBusinessMetadataDetailsAttrView();
+ if (fetch) {
+ enumDefCollection.fetch({ reset: true });
+ that.entityDefCollection.fetch({ silent: true });
+ }
+ },
+ businessMetadataDefCollection: that.businessMetadataDefCollection,
+ enumDefCollection: enumDefCollection,
+ typeHeaders: typeHeaders,
+ isNewBusinessMetadata: isNewBusinessMetadata
+ });
+ that.RModal.show(that.view);
+ });
+ },
+ renderTableLayoutView: function() {
+ var that = this;
+ require(['utils/TableLayout'], function(TableLayout) {
+ var cols = new Backgrid.Columns(that.getBusinessMetadataTableColumns());
+ that.RBusinessMetadataTableLayoutView.show(new TableLayout(_.extend({}, that.commonTableOptions, {
+ columns: cols
+ })));
+ if (!(that.businessMetadataDefCollection.models.length < that.limit)) {
+ that.RBusinessMetadataTableLayoutView.$el.find('table tr').last().hide();
+ }
+
+ });
+ },
+ getBusinessMetadataTableColumns: function() {
+ var that = this;
+ return this.businessMetadataDefCollection.constructor.getTableCols({
+ attributeDefs: {
+ label: "",
+ cell: "html",
+ editable: false,
+ sortable: false,
+ cell: Backgrid.ExpandableCell,
+ fixWidth: "20",
+ accordion: false,
+ alwaysVisible: true,
+ expand: function(el, model) {
+ el.attr('colspan', '8');
+ var attrValues = '',
+ attrTable = $('table'),
+ attrTableBody = $('tbody'),
+ attrTableHeading = "<thead><td style='display:table-cell'><b>Attribute</b></td><td style='display:table-cell'><b>Type</b></td><td style='display:table-cell'><b>Search Weight</b></td><td style='display:table-cell'><b>Enable Multivalues</b></td><td style='display:table-cell'><b>Max Length</b></td><td style='display:table-cell'><b>Applicable Type(s)</b></td><td style='display:table-cell'><b>Action</b></td></thead>",
+ attrRow = '',
+ attrTableDetails = '';
+ if (model.attributes && model.attributes.attributeDefs.length) {
+ _.each(model.attributes.attributeDefs, function(attrObj) {
+ var applicableEntityTypes = '',
+ typeName = attrObj.typeName,
+ multiSelect = '',
+ maxString = 'NA';
+ if (attrObj.options && attrObj.options.applicableEntityTypes) {
+ var entityTypes = JSON.parse(attrObj.options.applicableEntityTypes);
+ _.each(entityTypes, function(values) {
+ applicableEntityTypes += '<label class="btn btn-action btn-sm btn-blue no-pointer">' + values + '</label>';
+ })
+ }
+ if (typeName.includes('array')) {
+ typeName = _.escape(typeName);
+ multiSelect = 'checked';
+ }
+ if (typeName.includes('string') && attrObj.options && attrObj.options.maxStrLength) {
+ maxString = attrObj.options.maxStrLength;
+ }
+
+ attrRow += "<tr> <td style='display:table-cell'>" + _.escape(attrObj.name) + "</td><td style='display:table-cell'>" + typeName + "</td><td style='display:table-cell'>" + _.escape(attrObj.searchWeight) + "</td><td style='display:table-cell'><input type='checkbox' class='form-check-input multi-value-select' " + multiSelect + " disabled='disabled'> </td><td style='display:table-cell'>" + maxString + "</td><td style='display:table-cell'>" + applicableEntityTypes + "</td><td style='display:table-cell'> <div class='btn btn-action btn-sm' style='margin-left:0px;' data-id='attributeEdit' data-guid='" + model.get('guid') + "' data-name ='" + _.escape(attrObj.name) + "' data-action='attributeEdit' >Edit</div> </td></tr> ";
+ });
+ var adminText = '<div class="row"><div class="col-sm-12 attr-details"><table style="padding: 50px;">' + attrTableHeading + attrRow + '</table></div></div>';
+ $(el).append($('<div>').html(adminText));
+ } else {
+ var adminText = '<div class="row"><div class="col-sm-12 attr-details"><h5 class="text-center"> No attributes to show.</h5></div></div>';
+ $(el).append($('<div>').html(adminText));
+ }
+ }
+ },
+ name: {
+ label: "Name",
+ cell: "html",
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ return '<a title= "' + model.get('name') + '" href ="#!/administrator/businessMetadata/' + model.get('guid') + '?from=bm">' + model.get('name') + '</a>';
+ }
+ })
+ },
+ description: {
+ label: "Description",
+ cell: "html",
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ return model.get('description');
+ }
+ })
+ },
+ createdBy: {
+ label: "Created by",
+ cell: "html",
+ renderable: false,
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ return model.get('updatedBy');
+ }
+ })
+ },
+ createTime: {
+ label: "Created on",
+ cell: "html",
+ renderable: false,
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ return new Date(model.get('createTime'));
+ }
+ })
+ },
+ updatedBy: {
+ label: "Updated by",
+ cell: "html",
+ renderable: false,
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ return model.get('updatedBy');
+ }
+ })
+ },
+ updateTime: {
+ label: "Updated on",
+ cell: "html",
+ renderable: false,
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ return new Date(model.get('updateTime'));
+ }
+ })
+ },
+ tools: {
+ label: "Action",
+ cell: "html",
+ sortable: false,
+ editable: false,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ return "<button type='button' data-id='addAttribute' data-guid='" + model.get('guid') + "'' title='' class='btn btn-action btn-sm ' style='margin-bottom: 10px;' data-action='createAttr' data-original-title='Add Business Metadata attribute'><i class='fa fa-plus'></i> Attributes</button>";
+ }
+ })
+ }
+ }, this.businessMetadataDefCollection);
+ },
+ deleteBusinessMetadataElement: function(businessMetadataName) {
+ var that = this,
+ notifyObj = {
+ modal: true,
+ ok: function(argument) {
+ that.onNotifyDeleteOk();
+ },
+ cancel: function(argument) {}
+ };
+ var text = "Are you sure you want to delete the business metadata";
+ notifyObj["text"] = text;
+ Utils.notifyConfirm(notifyObj);
+ },
+ onNotifyDeleteOk: function(data) {
+ var that = this,
+ deleteBusinessMetadataData = that.businessMetadataDefCollection.fullCollection.findWhere({ guid: that.guid });
+ that.$('.tableOverlay').show();
+ if (deleteBusinessMetadataData) {
+ var businessMetadataName = deleteBusinessMetadataData.get("name");
+ deleteBusinessMetadataData.deleteBusinessMetadata({
+ typeName: businessMetadataName,
+ success: function() {
+ Utils.notifySuccess({
+ content: "Business Metadata " + businessMetadataName + Messages.getAbbreviationMsg(false, 'deleteSuccessMessage')
+ });
+ that.businessMetadataDefCollection.fullCollection.remove(deleteBusinessMetadataData);
+ that.businessMetadataDefCollection.fullCollection.sort({ silent: true });
+ that.renderTableLayoutView();
+ that.showDetails = true;
+ that.toggleBusinessMetadataDetailsAttrView();
+ that.loaderStatus(false);
+ },
+ complete: function() {
+ that.$('.tableOverlay').hide();
+ that.$('.position-relative .fontLoader').removeClass('show');
+ }
+ });
+ } else {
+ Utils.notifyError({
+ content: Messages.defaultErrorMessage
+ });
+ }
+ }
+ });
+ return BusinessMetadataTableLayoutView;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js b/dashboardv2/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js
new file mode 100644
index 0000000..761ef55
--- /dev/null
+++ b/dashboardv2/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js
@@ -0,0 +1,321 @@
+/**
+ * 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/business_metadata/CreateBusinessMetadataLayoutView_tmpl',
+ 'utils/Utils',
+ 'utils/Messages',
+ 'views/business_metadata/BusinessMetadataAttributeItemView',
+ 'models/VEntity'
+], function(require, Backbone, CreateBusinessMetadataLayoutViewTmpl, Utils, Messages, BusinessMetadataAttributeItemView, VEntity) {
+
+ var CreateBusinessMetadataLayoutView = Backbone.Marionette.CompositeView.extend(
+ /** @lends CreateBusinessMetadataLayoutView */
+ {
+ _viewName: 'CreateBusinessMetadataLayoutView',
+
+ template: CreateBusinessMetadataLayoutViewTmpl,
+
+ templateHelpers: function() {
+ return {
+ create: this.create,
+ description: this.description,
+ fromTable: this.fromTable,
+ isEditAttr: this.isEditAttr
+ };
+ },
+
+ /** Layout sub regions */
+ regions: {},
+
+ childView: BusinessMetadataAttributeItemView,
+
+ childViewContainer: "[data-id='addAttributeDiv']",
+
+ childViewOptions: function() {
+ return {
+ typeHeaders: this.typeHeaders,
+ businessMetadataDefCollection: this.businessMetadataDefCollection,
+ enumDefCollection: this.enumDefCollection,
+ isAttrEdit: this.isAttrEdit,
+ viewId: this.cid,
+ collection: this.collection
+ };
+ },
+ /** ui selector cache */
+ ui: {
+ name: "[data-id='name']",
+ description: "[data-id='description']",
+ title: "[data-id='title']",
+ attributeData: "[data-id='attributeData']",
+ addAttributeDiv: "[data-id='addAttributeDiv']",
+ createForm: '[data-id="createForm"]',
+ businessMetadataAttrPageCancle: '[data-id="businessMetadataAttrPageCancle"]',
+ businessMetadataAttrPageOk: '[data-id="businessMetadataAttrPageOk"]'
+ },
+ /** ui events hash */
+ events: function() {
+ var events = {};
+ events["click " + this.ui.attributeData] = "onClickAddAttriBtn";
+ events["click " + this.ui.businessMetadataAttrPageOk] = function(e) {
+ var that = this,
+ modal = that.$el;
+ if (e.target.dataset.action == "attributeEdit" || e.target.dataset.action == "addAttribute") {
+ that.onUpdateAttr();
+ } else {
+ that.onCreateBusinessMetadata();
+ }
+
+ };
+ events["click " + this.ui.businessMetadataAttrPageCancle] = function(e) {
+ this.options.onUpdateBusinessMetadata();
+ };
+ return events;
+ },
+ /**
+ * intialize a new CreateBusinessMetadataLayoutView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, _.pick(options, 'businessMetadataDefCollection', 'selectedBusinessMetadata', 'enumDefCollection', 'model', 'isNewBusinessMetadata', 'isAttrEdit', 'typeHeaders', 'attrDetails'));
+ this.fromTable = this.isNewBusinessMetadata ? true : false;
+ this.isEditAttr = this.isAttrEdit ? false : true;
+ this.businessMetadataModel = new VEntity();
+ if (this.model) {
+ this.description = this.model.get('description');
+ } else {
+ this.create = true;
+ }
+ if (!this.isNewBusinessMetadata) {
+ this.collection = this.isAttrEdit ? new Backbone.Collection([
+ this.attrDetails
+ ]) : new Backbone.Collection([{
+ "name": "",
+ "typeName": "string",
+ "isOptional": true,
+ "cardinality": "SINGLE",
+ "valuesMinCount": 0,
+ "valuesMaxCount": 1,
+ "isUnique": false,
+ "isIndexable": true
+ }]);
+ } else {
+ this.collection = new Backbone.Collection();
+ }
+
+ },
+ bindEvents: function() {},
+ onRender: function() {
+ var that = this;
+ this.$('.fontLoader').show();
+ if (!('placeholder' in HTMLInputElement.prototype)) {
+ this.ui.createForm.find('input,textarea').placeholder();
+ }
+ if (this.isNewBusinessMetadata == true) {
+ that.ui.businessMetadataAttrPageOk.text("Create");
+ that.ui.businessMetadataAttrPageOk.attr('data-action', 'newBusinessMetadata');
+ } else {
+ that.ui.businessMetadataAttrPageOk.text("Save");
+ that.ui.businessMetadataAttrPageOk.attr('data-action', 'attributeEdit');
+ }
+ this.hideLoader();
+ },
+ hideLoader: function() {
+ this.$('.fontLoader').hide();
+ this.$('.hide').removeClass('hide');
+ },
+ collectionAttribute: function() {
+ this.collection.add(new Backbone.Model({
+ "name": "",
+ "typeName": "string",
+ "isOptional": true,
+ "cardinality": "SINGLE",
+ "valuesMinCount": 0,
+ "valuesMaxCount": 1,
+ "isUnique": false,
+ "isIndexable": true
+ }));
+ },
+ onClickAddAttriBtn: function() {
+ this.collectionAttribute();
+ if (!('placeholder' in HTMLInputElement.prototype)) {
+ this.ui.addAttributeDiv.find('input,textarea').placeholder();
+ }
+ },
+ loaderStatus: function(isActive) {
+ var that = this;
+ if (isActive) {
+ parent.$('.business-metadata-attr-tableOverlay').show();
+ parent.$('.business-metadata-attr-fontLoader').show();
+ } else {
+ parent.$('.business-metadata-attr-tableOverlay').hide();
+ parent.$('.business-metadata-attr-fontLoader').hide();
+ }
+ },
+ validateValues: function(attributeDefs) {
+ var isValidate = true,
+ isAttrDuplicate = true,
+ validationFileds = this.$el.find('.require'),
+ attrNames = [];
+ if (attributeDefs && !this.isAttrEdit) {
+ attrNames = _.map(attributeDefs, function(model) {
+ return model.name.toLowerCase();
+ });
+ }
+ validationFileds.each(function(elements) {
+ $(this).removeClass('errorValidate');
+ if (validationFileds[elements].value == '' || validationFileds[elements].value == null) {
+ if (validationFileds[elements].style.display != 'none') {
+ $(validationFileds[elements]).addClass('errorValidate');
+ $(this).addClass('errorValidate');
+ if (isValidate) { isValidate = false; }
+ }
+ }
+ });
+ if (isValidate) {
+ this.$el.find('.attributeInput').each(function(element) {
+ var attrValue = this.value.toLowerCase();
+ if (attrNames.indexOf(attrValue) > -1) {
+ Utils.notifyInfo({
+ content: "Attribute name already exist"
+ });
+ $(this).addClass('errorValidate');
+ if (isAttrDuplicate) { isAttrDuplicate = false; }
+ } else {
+ if (attrValue.length) {
+ attrNames.push(attrValue);
+ }
+ }
+ });
+ }
+
+ if (!isValidate) {
+ Utils.notifyInfo({
+ content: "Please fill the details"
+ });
+ return true;
+ }
+ if (!isAttrDuplicate) {
+ return true;
+ }
+
+ },
+ onCreateBusinessMetadata: function() {
+ var that = this;
+ if (this.validateValues()) {
+ return;
+ };
+ this.loaderStatus(true);
+ var name = this.ui.name.val(),
+ description = _.escape(this.ui.description.val());
+ var attributeObj = this.collection.toJSON();
+ if (this.collection.length === 1 && this.collection.first().get("name") === "") {
+ attributeObj = [];
+ }
+ this.json = {
+ "enumDefs": [],
+ "structDefs": [],
+ "classificationDefs": [],
+ "entityDefs": [],
+ "businessMetadataDefs": [{
+ "category": "BUSINESS_METADATA",
+ "createdBy": "admin",
+ "updatedBy": "admin",
+ "version": 1,
+ "typeVersion": "1.1",
+ "name": name.trim(),
+ "description": description.trim(),
+ "attributeDefs": attributeObj
+ }]
+ };
+ var apiObj = {
+ sort: false,
+ data: this.json,
+ success: function(model, response) {
+ var nameSpaveDef = model.businessMetadataDefs;
+ if (nameSpaveDef) {
+ that.businessMetadataDefCollection.fullCollection.add(nameSpaveDef);
+ Utils.notifySuccess({
+ content: "Business Metadata " + name + Messages.getAbbreviationMsg(false, 'addSuccessMessage')
+ });
+ }
+ that.options.onUpdateBusinessMetadata(true);
+ },
+ silent: true,
+ reset: true,
+ complete: function(model, status) {
+ that.loaderStatus(false);
+ }
+ }
+ apiObj.type = "POST";
+ that.businessMetadataModel.saveBusinessMetadata(apiObj);
+ },
+ onUpdateAttr: function() {
+ var that = this,
+ selectedBusinessMetadataClone = $.extend(true, {}, that.selectedBusinessMetadata.toJSON()),
+ attributeDefs = selectedBusinessMetadataClone['attributeDefs'],
+ isvalidName = true;
+ if (this.validateValues(attributeDefs)) {
+ return;
+ };
+ if (this.collection.length > 0) {
+ this.loaderStatus(true);
+ if (selectedBusinessMetadataClone.attributeDefs === undefined) {
+ selectedBusinessMetadataClone.attributeDefs = [];
+ }
+ selectedBusinessMetadataClone.attributeDefs = selectedBusinessMetadataClone.attributeDefs.concat(this.collection.toJSON());
+ this.json = {
+ "enumDefs": [],
+ "structDefs": [],
+ "classificationDefs": [],
+ "entityDefs": [],
+ "businessMetadataDefs": [selectedBusinessMetadataClone]
+ };
+ var apiObj = {
+ sort: false,
+ data: this.json,
+ success: function(model, response) {
+ Utils.notifySuccess({
+ content: "One or more Business Metadada attribute" + Messages.getAbbreviationMsg(true, 'editSuccessMessage')
+ });
+ if (model.businessMetadataDefs && model.businessMetadataDefs.length) {
+ that.selectedBusinessMetadata.set(model.businessMetadataDefs[0]);
+ }
+ that.options.onEditCallback();
+ that.options.onUpdateBusinessMetadata(true);
+ },
+ silent: true,
+ reset: true,
+ complete: function(model, status) {
+ that.loaderStatus(false);
+ }
+ }
+ apiObj.type = "PUT";
+ that.businessMetadataModel.saveBusinessMetadata(apiObj);
+ } else {
+ Utils.notifySuccess({
+ content: "No attribute updated"
+ });
+ this.loaderStatus(false);
+ that.options.onUpdateBusinessMetadata();
+ }
+ }
+ });
+ return CreateBusinessMetadataLayoutView;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/business_metadata/EnumCreateUpdateItemView.js b/dashboardv2/public/js/views/business_metadata/EnumCreateUpdateItemView.js
new file mode 100644
index 0000000..08960a6
--- /dev/null
+++ b/dashboardv2/public/js/views/business_metadata/EnumCreateUpdateItemView.js
@@ -0,0 +1,267 @@
+/*
+ * 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/business_metadata/EnumCreateUpdateItemView_tmpl", "utils/Utils", "utils/UrlLinks"], function(
+ require,
+ Backbone,
+ EnumCreateUpdateItemViewTmpl,
+ Utils,
+ UrlLinks
+) {
+ "use strict";
+
+ return Backbone.Marionette.ItemView.extend(
+ /** @lends GlobalExclusionListView */
+ {
+ template: EnumCreateUpdateItemViewTmpl,
+
+ /** Layout sub regions */
+ regions: {},
+
+ /** ui selector cache */
+ ui: {
+ enumTypeSelectorContainer: "[data-id='enumTypeSelectorContainer']",
+ enumSelector: "[data-id='enumSelector']",
+ enumValueSelectorContainer: "[data-id='enumValueSelectorContainer']",
+ valueSelector: "[data-id='valueSelector']",
+ enumCancleBtn: "[data-id='enumCancleBtn']",
+ enumOkBtn: "[data-id='enumOkBtn']"
+ },
+ /** ui events hash */
+ events: function() {
+ var events = {};
+ events["change " + this.ui.enumSelector] = function(e) {
+ this.model.set({ enumValues: e.target.value.trim() });
+ };
+ events["change " + this.ui.enumSelector] = function(e) {
+ var emumValue = this.ui.enumSelector.select2("data")[0] ?
+ this.ui.enumSelector.select2("data")[0].text :
+ this.ui.enumSelector.val();
+ if (emumValue == "" || emumValue == null) {
+ this.ui.enumValueSelectorContainer.hide();
+ } else {
+ this.ui.enumValueSelectorContainer.show();
+ this.showEnumValues(emumValue);
+ }
+ };
+ events["change " + this.ui.valueSelector] = function(e) {};
+ events["click " + this.ui.enumCancleBtn] = function(e) {
+ if (this.options.closeModal) {
+ this.options.closeModal();
+ return;
+ }
+ this.ui.enumValueSelectorContainer.hide();
+ this.ui.enumSelector.val("").trigger("change");
+ this.ui.enumCancleBtn.attr("disabled", "true");
+ };
+ events["click " + this.ui.enumOkBtn] = function(e) {
+ this.ui.enumCancleBtn.attr("disabled", "true");
+ this.onUpdateEnum();
+ };
+ return events;
+ },
+
+ /**
+ * intialize a new GlobalExclusionComponentView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, _.pick(options, "businessMetadataDefCollection", "enumDefCollection"));
+ },
+ onRender: function() {
+ this.ui.enumValueSelectorContainer.hide();
+ this.bindEvents();
+ this.emumTypeSelectDisplay();
+ if (!this.options.closeModal) {
+ this.ui.enumCancleBtn.attr("disabled", "true");
+ this.ui.enumCancleBtn.text("Clear");
+ }
+ },
+ bindEvents: function() {
+ var that = this;
+ this.listenTo(this.enumDefCollection, 'reset', function() {
+ that.emumTypeSelectDisplay();
+ })
+ },
+
+ showEnumValues: function(enumName) {
+ var enumValues = "",
+ selectedValues = [],
+ selectedEnum = this.enumDefCollection.fullCollection.findWhere({ name: enumName }),
+ selectedEnumValues = selectedEnum ? selectedEnum.get("elementDefs") : null;
+ _.each(selectedEnumValues, function(enumVal, index) {
+ selectedValues.push(_.unescape(enumVal.value));
+ enumValues += "<option>" + enumVal.value + "</option>";
+ });
+
+ this.ui.enumCancleBtn.removeAttr("disabled");
+ this.ui.valueSelector.empty();
+ this.ui.valueSelector.append(enumValues);
+ this.ui.valueSelector.val(selectedValues);
+ this.ui.valueSelector.select2({
+ placeholder: "Select Enum value",
+ allowClear: false,
+ tags: true,
+ multiple: true
+ });
+ },
+ emumTypeSelectDisplay: function() {
+ var enumTypes = "";
+ this.enumDefCollection.fullCollection.each(function(model, index) {
+ enumTypes += "<option>" + _.escape(model.get("name")) + "</option>";
+ });
+ this.ui.enumSelector.empty();
+ this.ui.enumSelector.append(enumTypes);
+ this.ui.enumSelector.val("");
+ this.ui.enumSelector.select2({
+ placeholder: "Select Enum name",
+ tags: true,
+ allowClear: true,
+ multiple: false,
+ templateResult: this.formatSearchResult
+ });
+ },
+ formatSearchResult: function(state) {
+ if (!state.id) {
+ return state.text;
+ }
+ if (!state.element) {
+ return $("<span>Create new enum : <strong> " + _.escape(state.text) + "</strong></span>");
+ } else {
+ return $("<span>" + _.escape(state.text) + "</span>");
+ }
+ },
+ validationEnum: function() {
+ var selectedEnumName = this.ui.enumSelector.val(),
+ selectedEnumValues = this.ui.valueSelector.val();
+
+ if (selectedEnumName == "" || selectedEnumName == null) {
+ this.ui.enumOkBtn.hideButtonLoader();
+ Utils.notifyInfo({
+ content: "Please enter the Enumeration Name"
+ });
+ return true;
+ }
+ if (selectedEnumValues == "" || selectedEnumValues == null) {
+ this.ui.enumOkBtn.hideButtonLoader();
+ Utils.notifyInfo({
+ content: "Please enter the Enum values"
+ });
+ return true;
+ }
+ },
+ onUpdateEnum: function(view, modal) {
+ var that = this,
+ selectedEnumName = this.ui.enumSelector.val(),
+ selectedEnumValues = this.ui.valueSelector.val(),
+ enumName = this.enumDefCollection.fullCollection.findWhere({ name: selectedEnumName }),
+ isPutCall = false,
+ isPostCallEnum = false,
+ enumDefs = [];
+ if (this.validationEnum()) {
+ return;
+ }
+ this.ui.enumOkBtn.showButtonLoader();
+ this.ui.enumSelector.attr("disabled", "true");
+ this.ui.valueSelector.attr("disabled", "true");
+ this.ui.enumCancleBtn.attr("disabled", "true");
+ if (enumName) {
+ var enumDef = enumName.get("elementDefs");
+ if (enumDef.length === selectedEnumValues.length) {
+ _.each(enumDef, function(enumVal, index) {
+ if (selectedEnumValues.indexOf(enumVal.value) === -1) {
+ isPutCall = true;
+ }
+ });
+ } else {
+ isPutCall = true;
+ }
+ } else {
+ isPostCallEnum = true;
+ }
+ var elementValues = [];
+ _.each(selectedEnumValues, function(inputEnumVal, index) {
+ elementValues.push({
+ ordinal: index + 1,
+ value: _.escape(inputEnumVal)
+ });
+ });
+
+ enumDefs.push({
+ name: selectedEnumName,
+ elementDefs: elementValues
+ });
+
+ this.json = {
+ enumDefs: enumDefs
+ };
+ var apiObj = {
+ sort: false,
+ success: function(model, response) {
+ that.ui.enumValueSelectorContainer.hide();
+ if (isPostCallEnum) {
+ that.enumDefCollection.add(model.enumDefs[0]);
+ Utils.notifySuccess({
+ content: "Enumeration " + selectedEnumName + " added successfully"
+ });
+ } else {
+ var foundEnum = that.enumDefCollection.fullCollection.find({ guid: model.enumDefs[0].guid })
+ if (foundEnum) {
+ foundEnum.set(model.enumDefs[0]);
+ }
+ Utils.notifySuccess({
+ content: "Enumeration " + selectedEnumName + " updated successfully"
+ });
+ }
+ that.enumDefCollection.fetch({ reset: true });
+ if (that.options.onUpdateEnum) { //callback from BusinessMetadataAttributeItemView
+ that.options.onUpdateEnum();
+ }
+ that.ui.enumCancleBtn.attr("disabled", "true");
+ },
+ silent: true,
+ reset: true,
+ complete: function(model, status) {
+ that.emumTypeSelectDisplay();
+ that.ui.enumOkBtn.hideButtonLoader();
+ that.ui.enumSelector.removeAttr("disabled");
+ that.ui.valueSelector.removeAttr("disabled");
+ if (that.options.closeModal) {
+ that.options.closeModal();
+ }
+ }
+ };
+ $.extend(apiObj, { contentType: "application/json", dataType: "json", data: JSON.stringify(this.json) });
+ if (isPostCallEnum) {
+ this.businessMetadataDefCollection.constructor.nonCrudOperation.call(this, UrlLinks.typedefsUrl().defs, "POST", apiObj);
+ } else if (isPutCall) {
+ this.businessMetadataDefCollection.constructor.nonCrudOperation.call(this, UrlLinks.typedefsUrl().defs, "PUT", apiObj);
+ } else {
+ Utils.notifySuccess({
+ content: "No updated values"
+ });
+ that.ui.enumOkBtn.hideButtonLoader();
+ that.ui.enumSelector.removeAttr("disabled");
+ that.ui.valueSelector.removeAttr("disabled");
+ if (that.options.closeModal) {
+ that.options.closeModal();
+ }
+ }
+ }
+ }
+ );
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
index ccb8fad..84b9c78 100644
--- a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
+++ b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
@@ -46,7 +46,8 @@
RProfileLayoutView: "#r_profileLayoutView",
RRelationshipLayoutView: "#r_relationshipLayoutView",
REntityUserDefineView: "#r_entityUserDefineView",
- REntityLabelDefineView: "#r_entityLabelDefineView"
+ REntityLabelDefineView: "#r_entityLabelDefineView",
+ REntityBusinessMetadataView: "#r_entityBusinessMetadataView"
},
/** ui selector cache */
ui: {
@@ -108,6 +109,7 @@
});
};
+
return events;
},
/**
@@ -115,7 +117,7 @@
* @constructs
*/
initialize: function(options) {
- _.extend(this, _.pick(options, 'value', 'collection', 'id', 'entityDefCollection', 'typeHeaders', 'enumDefCollection', 'classificationDefCollection', 'glossaryCollection'));
+ _.extend(this, _.pick(options, 'value', 'collection', 'id', 'entityDefCollection', 'typeHeaders', 'enumDefCollection', 'classificationDefCollection', 'glossaryCollection', 'businessMetadataDefCollection', 'searchVent'));
$('body').addClass("detail-page");
},
bindEvents: function() {
@@ -242,6 +244,8 @@
enumDefCollection: this.enumDefCollection,
classificationDefCollection: this.classificationDefCollection,
glossaryCollection: this.glossaryCollection,
+ businessMetadataCollection: this.activeEntityDef.get('businessAttributeDefs'),
+ searchVent: this.searchVent,
attributeDefs: (function() {
return that.getEntityDef(collectionJSON);
})(),
@@ -253,6 +257,9 @@
this.renderEntityDetailTableLayoutView(obj);
this.renderEntityUserDefineView(obj);
this.renderEntityLabelDefineView(obj);
+ if (obj.businessMetadataCollection) {
+ this.renderEntityBusinessMetadataView(obj);
+ }
this.renderRelationshipLayoutView(obj);
this.renderAuditTableLayoutView(obj);
this.renderTagTableLayoutView(obj);
@@ -371,6 +378,9 @@
hideLoader: that.hideLoader.bind(that),
tagName: tagName,
callback: function() {
+ if (that.searchVent) {
+ that.searchVent.trigger("Classification:Count:Update");
+ }
that.fetchCollection();
}
}));
@@ -454,6 +464,9 @@
guid: that.id,
tagList: tagList,
callback: function() {
+ if (that.searchVent) {
+ that.searchVent.trigger("Classification:Count:Update");
+ }
that.fetchCollection();
},
showLoader: that.showLoader.bind(that),
@@ -506,6 +519,12 @@
that.REntityLabelDefineView.show(new EntityLabelDefineView(obj));
});
},
+ renderEntityBusinessMetadataView: function(obj) {
+ var that = this;
+ require(['views/entity/EntityBusinessMetaDataView'], function(EntityBusinessMetaDataView) {
+ that.REntityBusinessMetadataView.show(new EntityBusinessMetaDataView(obj));
+ });
+ },
renderTagTableLayoutView: function(obj) {
var that = this;
require(['views/tag/TagDetailTableLayoutView'], function(TagDetailTableLayoutView) {
diff --git a/dashboardv2/public/js/views/entity/EntityBusinessMetaDataItemView.js b/dashboardv2/public/js/views/entity/EntityBusinessMetaDataItemView.js
new file mode 100644
index 0000000..437a1fc
--- /dev/null
+++ b/dashboardv2/public/js/views/entity/EntityBusinessMetaDataItemView.js
@@ -0,0 +1,349 @@
+/*
+ * 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/entity/EntityBusinessMetaDataItemView_tmpl',
+ 'moment',
+ 'daterangepicker'
+], function(require, Backbone, EntityBusinessMetaDataItemViewTmpl, moment) {
+ 'use strict';
+
+ return Backbone.Marionette.ItemView.extend({
+ _viewName: 'EntityBusinessMetaDataItemView',
+
+ template: EntityBusinessMetaDataItemViewTmpl,
+
+ templateHelpers: function() {
+ return {
+ editMode: this.editMode,
+ entity: this.entity,
+ getValue: this.getValue.bind(this),
+ getBusinessMetadataDroupdown: this.getBusinessMetadataDroupdown.bind(this),
+ businessMetadataCollection: this.businessMetadataCollection,
+ model: this.model.toJSON()
+ }
+ },
+ tagName: 'li',
+ className: "business-metadata-tree-child",
+
+ /** Layout sub regions */
+ regions: {},
+
+ /** ui selector cache */
+ ui: {
+ keyEl: "[data-id='key']",
+ valueEl: "[data-type='value']",
+ addItem: "[data-id='addItem']",
+ deleteItem: "[data-id='deleteItem']",
+ editMode: "[data-id='editMode']"
+ },
+ /** ui events hash */
+ events: function() {
+ var events = {};
+ events["click " + this.ui.deleteItem] = 'onDeleteItem';
+ events["change " + this.ui.keyEl] = 'onAttrChange';
+ return events;
+ },
+
+ /**
+ * intialize a new EntityBusinessMetaDataItemView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, options);
+ },
+ onRender: function() {
+ var that = this;
+ this.ui.keyEl.val("");
+ this.ui.keyEl.select2({ placeholder: "Select Attribute" });
+
+ if (this.editMode && (!this.model.has("isNew"))) {
+ this.getEditBusinessMetadataEl();
+ }
+ this.initializeElement();
+ this.bindEvent();
+ },
+ initializeElement: function() {},
+ bindEvent: function() {
+ var that = this;
+ if (this.editMode) {
+ this.listenTo(this.model.collection, 'destroy unset:attr', function() {
+ if (this.model.has("isNew")) {
+ this.render();
+ }
+ });
+ this.listenTo(this.model.collection, 'selected:attr', function(value, model) {
+ if (model.cid !== this.model.cid && this.model.has("isNew")) {
+ var $select2el = that.$el.find('.custom-col-1:first-child>select[data-id="key"]');
+ $select2el.find('option[value="' + value + '"]').remove();
+ var select2val = $select2el.select2("val");
+ $select2el.select2({ placeholder: "Select Attribute" });
+ if (this.model.keys().length <= 2) {
+ $select2el.val("").trigger("change", true);
+ }
+ }
+ });
+ this.$el.off("change", ".custom-col-1[data-id='value']>[data-key]").on("change", ".custom-col-1[data-id='value']>[data-key]", function(e) {
+ var key = $(this).data("key"),
+ businessMetadata = $(this).data("businessMetadata"),
+ typeName = $(this).data("typename"),
+ multi = $(this).data("multi"),
+ updateObj = that.model.toJSON();
+ if (_.isUndefinedNull(updateObj[key])) {
+ updateObj[key] = { value: null, typeName: typeName };
+ }
+ updateObj[key].value = e.currentTarget.value;
+ if (multi && typeName.indexOf("date") == -1) {
+ updateObj[key].value = $(this).select2("val");
+ }
+ if (!that.model.has("__internal_UI_businessMetadataName")) {
+ updateObj["__internal_UI_businessMetadataName"] = businessMetadata;
+ }
+ if (typeName.indexOf("date") > -1) {
+ if (multi && updateObj[key].value) {
+ var dateValues = updateObj[key].value.split(','),
+ dateStr = [];
+ if (dateValues.length) {
+ _.each(dateValues, function(selectedDate) {
+ dateStr.push(new Date(selectedDate.trim()).getTime());
+ });
+ updateObj[key].value = dateStr;
+ }
+ } else {
+ updateObj[key].value = new Date(updateObj[key].value).getTime()
+ }
+ }
+ that.model.set(updateObj);
+ });
+ this.$el.on('keypress', '.select2_only_number .select2-search__field', function() {
+ var typename = $(this).parents(".select2_only_number").find("select[data-typename]").data("typename")
+ if (typename.indexOf("float") > -1 && event.which == 46) {
+ return;
+ }
+ if ((event.which < 48 || event.which > 57)) {
+
+ event.preventDefault();
+ }
+ });
+ }
+ },
+ getAttrElement: function(opt) {
+ var that = this,
+ returnEL = "N/A",
+ options = $.extend(true, {}, opt);
+ if (options) {
+ var key = options.key,
+ typeName = options.val.typeName || "",
+ val = options.val.value,
+ isMultiValued = typeName && typeName.indexOf("array<") === 0,
+ businessMetadata = options.businessMetadata,
+ allowOnlyNum = false;
+ var elType = isMultiValued ? "select" : "input";
+ if (!isMultiValued && !_.isEmpty(val)) {
+ val = _.escape(val);
+ }
+ if (!_.isUndefinedNull(val) && typeName.indexOf("boolean") > -1) {
+ val = String(val);
+ }
+ if (typeName.indexOf("date") > -1) {
+ if (isMultiValued && val && val.length) {
+ var dateStr = [];
+ _.each(val, function(selectedDate) {
+ selectedDate = parseInt(selectedDate);
+ dateStr.push(moment(selectedDate).format("MM/DD/YYYY"));
+ });
+ val = dateStr.join(',');
+ } else if (!isMultiValued && val) {
+ val = parseInt(val);
+ val = moment(val).format("MM/DD/YYYY");
+ }
+ }
+ if (typeName.indexOf("string") > -1) {
+ returnEL = '<' + elType + ' type="text" data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '" data-multi="' + isMultiValued + '" data-tags="true" placeholder="Enter String" class="form-control" ' + (!_.isUndefinedNull(val) ? 'value="' + val + '"' : "") + '></' + elType + '>';
+ } else if (typeName.indexOf("boolean") > -1) {
+ returnEL = '<select data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '" data-multi="' + isMultiValued + '" class="form-control">' + (isMultiValued ? "" : '<option value="">--Select Value--</option>') + '<option value="true" ' + (!_.isUndefinedNull(val) && val == "true" ? "selected" : "") + '>true</option><option value="false" ' + (!_.isUndefinedNull(val) && val == "false" ? "selected" : "") + '>false</option></select>';
+ } else if (typeName.indexOf("date") > -1) {
+ returnEL = '<' + (isMultiValued ? "textarea" : "input") + ' type="text" data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '"data-multi="' + isMultiValued + '" data-type="date" class="form-control" ' + (isMultiValued === false && !_.isUndefinedNull(val) ? 'value="' + val + '"' : "") + '>' + (isMultiValued === true && !_.isUndefinedNull(val) ? val : "") + (isMultiValued ? "</textarea>" : "");
+ setTimeout(function() {
+ var dateObj = { singleDatePicker: true, showDropdowns: true, autoUpdateInput: isMultiValued ? false : true },
+ dateEl = that.$el.find('[data-type="date"][data-key="' + key + '"]').daterangepicker(dateObj);
+ if (isMultiValued) {
+ dateEl.on("apply.daterangepicker", function(ev, picker) {
+ var val = picker.element.val();
+ if (val !== "") {
+ val += ", ";
+ }
+ picker.element.val(val += picker.startDate.format('MM/DD/YYYY'));
+ that.$el.find(".custom-col-1[data-id='value']>[data-key]").trigger('change');
+ });
+ }
+ }, 0);
+ } else if (typeName.indexOf("byte") > -1 || typeName.indexOf("short") > -1 || typeName.indexOf("int") > -1 || typeName.indexOf("float") > -1 || typeName.indexOf("double") > -1 || typeName.indexOf("long") > -1) {
+ allowOnlyNum = true;
+ returnEL = '<' + elType + ' data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '" type="number" data-multi="' + isMultiValued + '" data-tags="true" placeholder="Enter Number" class="form-control" ' + (!_.isUndefinedNull(val) ? 'value="' + val + '"' : "") + '></' + elType + '>';
+ } else if (typeName) {
+ var modTypeName = typeName;
+ if (isMultiValued) {
+ var multipleType = typeName.match("array<(.*)>");
+ if (multipleType && multipleType[1]) {
+ modTypeName = multipleType[1];
+ }
+ }
+ var foundEnumType = this.enumDefCollection.fullCollection.find({ name: modTypeName });
+ if (foundEnumType) {
+ var enumOptions = "";
+ _.forEach(foundEnumType.get("elementDefs"), function(obj) {
+ enumOptions += '<option value="' + obj.value + '">' + obj.value + '</option>'
+ });
+ returnEL = '<select data-key="' + key + '" data-businessMetadata="' + businessMetadata + '" data-typename="' + typeName + '" data-multi="' + isMultiValued + '" >' + enumOptions + '</select>';
+ }
+ setTimeout(function() {
+ if (!isMultiValued) {
+ var selectEl = that.$el.find('.custom-col-1[data-id="value"] select[data-key="' + key + '"]');
+ selectEl.val((val || ""));
+ selectEl.select2();
+ }
+ }, 0);
+ }
+ if (isMultiValued) {
+ setTimeout(function() {
+ var selectEl = that.$el.find('.custom-col-1[data-id="value"] select[data-key="' + key + '"][data-multi="true"]');
+ var data = val && val.length && (_.isArray(val) ? val : val.split(",")) || [];
+ if (allowOnlyNum) {
+ selectEl.parent().addClass("select2_only_number");
+ }
+ selectEl.select2({
+ tags: selectEl.data("tags") ? true : false,
+ multiple: true,
+ data: data
+ });
+ selectEl.val(data).trigger("change");
+ }, 0);
+ }
+ }
+ return returnEL;
+ },
+ onAttrChange: function(e, manual) {
+ var key = e.currentTarget.value.split(":");
+ if (key.length && key.length === 3) {
+ var valEl = $(e.currentTarget).parent().siblings(".custom-col-1"),
+ hasModalData = this.model.get(key[1]);
+ if (!hasModalData) {
+ var tempObj = {
+ "__internal_UI_businessMetadataName": key[0]
+ };
+ if (this.model.has("isNew")) {
+ tempObj["isNew"] = true;
+ }
+ tempObj[key[1]] = null;
+ this.model.clear({ silent: true }).set(tempObj)
+ }
+ valEl.html(this.getAttrElement({ businessMetadata: key[0], key: key[1], val: hasModalData ? hasModalData : { typeName: key[2] } }));
+ if (manual === undefined) {
+ this.model.collection.trigger("selected:attr", e.currentTarget.value, this.model);
+ }
+ }
+ },
+ getValue: function(value, key, businessMetadataName) {
+ var typeName = value.typeName,
+ value = value.value;
+ if (typeName === "date") {
+ return moment(value).format("MM/DD/YYYY");
+ } else {
+ return value;
+ }
+ },
+ getBusinessMetadataDroupdown: function(businessMetadataCollection) {
+ var optgroup = "";
+ var that = this;
+ var model = that.model.omit(["isNew", "__internal_UI_businessMetadataName"]),
+ keys = _.keys(model),
+ isSelected = false,
+ selectdVal = null;
+ if (keys.length === 1) {
+ isSelected = true;
+ }
+ _.each(businessMetadataCollection, function(obj, key) {
+ var options = "";
+ if (obj.length) {
+ _.each(obj, function(attrObj) {
+ var entityBusinessMetadata = that.model.collection.filter({ __internal_UI_businessMetadataName: key }),
+ hasAttr = false;
+ if (entityBusinessMetadata) {
+ var found = entityBusinessMetadata.find(function(eObj) {
+ return eObj.attributes.hasOwnProperty(attrObj.name);
+ });
+ if (found) {
+ hasAttr = true;
+ }
+ }
+ if ((isSelected && keys[0] === attrObj.name) || !(hasAttr)) {
+ var value = key + ":" + attrObj.name + ":" + attrObj.typeName;
+ if (isSelected && keys[0] === attrObj.name) { selectdVal = value };
+ options += '<option value="' + value + '">' + attrObj.name + ' (' + _.escape(attrObj.typeName) + ')</option>';
+ }
+ });
+ if (options.length) {
+ optgroup += '<optgroup label="' + key + '">' + options + '</optgroup>';
+ }
+ }
+ });
+
+ setTimeout(function() {
+ if (selectdVal) {
+ that.$el.find('.custom-col-1:first-child>select[data-id="key"]').val(selectdVal).trigger("change", true);
+ } else {
+ that.$el.find('.custom-col-1:first-child>select[data-id="key"]').val("").trigger("change", true);
+ }
+ }, 0);
+ return '<select data-id="key">' + optgroup + '</select>';
+ },
+ getEditBusinessMetadataEl: function() {
+ var that = this,
+ trs = "";
+ _.each(this.model.attributes, function(val, key) {
+ if (key !== "__internal_UI_businessMetadataName" && key !== "isNew") {
+ var td = '<td class="custom-col-1" data-key=' + key + '>' + key + ' (' + _.escape(val.typeName) + ')</td><td class="custom-col-0">:</td><td class="custom-col-1" data-id="value">' + that.getAttrElement({ businessMetadata: that.model.get("__internal_UI_businessMetadataName"), key: key, val: val }) + '</td>';
+
+ td += '<td class="custom-col-2 btn-group">' +
+ '<button class="btn btn-default btn-sm" data-key="' + key + '" data-id="deleteItem">' +
+ '<i class="fa fa-times"> </i>' +
+ '</button></td>';
+ trs += "<tr class='custom-tr'>" + td + "</tr>";
+ }
+ })
+ this.$("[data-id='businessMetadataTreeChild']").html("<table class='custom-table'>" + trs + "</table>");
+ },
+ onDeleteItem: function(e) {
+ var key = $(e.currentTarget).data("key");
+ if (this.model.has(key)) {
+ if (this.model.keys().length === 2) {
+ this.model.destroy();
+ } else {
+ this.model.unset(key);
+ if (!this.model.has("isNew")) {
+ this.$el.find("tr>td:first-child[data-key='" + key + "']").parent().remove()
+ }
+ this.model.collection.trigger("unset:attr");
+ }
+ } else {
+ this.model.destroy();
+ }
+ }
+ });
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/entity/EntityBusinessMetaDataView.js b/dashboardv2/public/js/views/entity/EntityBusinessMetaDataView.js
new file mode 100644
index 0000000..5bf0e28
--- /dev/null
+++ b/dashboardv2/public/js/views/entity/EntityBusinessMetaDataView.js
@@ -0,0 +1,259 @@
+/**
+ * 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/entity/EntityBusinessMetaDataView_tmpl",
+ "views/entity/EntityBusinessMetaDataItemView",
+ "models/VEntity",
+ "utils/Utils",
+ "utils/Messages",
+ "utils/CommonViewFunction",
+ 'moment'
+], function(require, Backbone, EntityBusinessMetaDataView_tmpl, EntityBusinessMetaDataItemView, VEntity, Utils, Messages, CommonViewFunction, moment) {
+ "use strict";
+
+ return Backbone.Marionette.CompositeView.extend({
+ _viewName: "EntityBusinessMetaDataView",
+ template: EntityBusinessMetaDataView_tmpl,
+ childView: EntityBusinessMetaDataItemView,
+ childViewContainer: "[data-id='itemView']",
+ childViewOptions: function() {
+ return {
+ editMode: this.editMode,
+ entity: this.entity,
+ businessMetadataCollection: this.businessMetadataCollection,
+ enumDefCollection: this.enumDefCollection
+ };
+ },
+ /** ui selector cache */
+ ui: {
+ addItem: "[data-id='addItem']",
+ addBusinessMetadata: "[data-id='addBusinessMetadata']",
+ saveBusinessMetadata: "[data-id='saveBusinessMetadata']",
+ businessMetadataTree: "[data-id='businessMetadataTree']",
+ cancel: "[data-id='cancel']"
+ },
+ events: function() {
+ var events = {};
+ events["click " + this.ui.addItem] = 'createNameElement';
+ events["click " + this.ui.addBusinessMetadata] = "onAddBusinessMetadata";
+ events["click " + this.ui.saveBusinessMetadata] = "onSaveBusinessMetadata";
+ events["click " + this.ui.cancel] = "onCancel";
+ return events;
+ },
+ initialize: function(options) {
+ var that = this;
+ _.extend(this, _.pick(options, "entity", "businessMetadataCollection", "enumDefCollection", "guid", "fetchCollection"));
+ this.editMode = false;
+ this.$("editBox").hide();
+ this.actualCollection = new Backbone.Collection(
+ _.map(this.entity.businessAttributes, function(val, key) {
+ var foundBusinessMetadata = that.businessMetadataCollection[key];
+ if (foundBusinessMetadata) {
+ _.each(val, function(aVal, aKey) {
+ var foundAttr = _.find(foundBusinessMetadata, function(o) {
+ return o.name === aKey
+ });
+ if (foundAttr) {
+ val[aKey] = { value: aVal, typeName: foundAttr.typeName };
+ }
+ })
+ }
+ return _.extend({}, val, { __internal_UI_businessMetadataName: key });
+ }));
+ this.collection = new Backbone.Collection();
+ this.entityModel = new VEntity();
+ },
+ updateToActualData: function(options) {
+ var silent = options && options.silent || false;
+ this.collection.reset($.extend(true, [], this.actualCollection.toJSON()), { silent: silent });
+ },
+ onAddBusinessMetadata: function() {
+ this.ui.addBusinessMetadata.hide();
+ this.ui.saveBusinessMetadata.show();
+ this.ui.cancel.show();
+ this.editMode = true;
+ this.ui.businessMetadataTree.hide();
+ this.$(".editBox").show();
+ this.updateToActualData({ silent: true });
+ if (this.collection.length === 0) {
+ this.createNameElement();
+ } else {
+ this.collection.trigger("reset");
+ }
+ this.panelOpenClose();
+ },
+ onCancel: function() {
+ this.ui.cancel.hide();
+ this.ui.saveBusinessMetadata.hide();
+ this.ui.addBusinessMetadata.show();
+ this.editMode = false;
+ this.ui.businessMetadataTree.show();
+ this.$(".editBox").hide();
+ this.updateToActualData();
+ this.panelOpenClose();
+ },
+ panelOpenClose: function() {
+ var collection = this.editMode ? this.collection : this.actualCollection;
+ if (collection && collection.length === 0) {
+ this.$el.find(".panel-heading").addClass("collapsed").attr('aria-expanded',false);
+ this.$el.find(".panel-collapse.collapse").removeClass("in");
+ this.ui.addBusinessMetadata.text("Add");
+ } else {
+ this.ui.addBusinessMetadata.text("Edit");
+ this.$el.find(".panel-heading").removeClass("collapsed").attr('aria-expanded',true);
+ this.$el.find(".panel-collapse.collapse").addClass("in");
+ }
+ },
+ validate: function() {
+ var validation = true;
+ this.$el.find('.custom-col-1[data-id="value"] [data-key]').each(function(el) {
+ var val = $(this).val(),
+ elIsSelect2 = $(this).hasClass("select2-hidden-accessible");
+ if (_.isString(val)) {
+ val = val.trim();
+ }
+ if (_.isEmpty(val)) {
+ if (validation) {
+ validation = false;
+ }
+ if (elIsSelect2) {
+ $(this).siblings(".select2").find(".select2-selection").attr("style", "border-color : red !important");
+ } else {
+ $(this).css("borderColor", "red");
+ }
+ } else {
+ if (elIsSelect2) {
+ $(this).siblings(".select2").find(".select2-selection").attr("style", "");
+ } else {
+ $(this).css("borderColor", "");
+ }
+ }
+ });
+ return validation;
+ },
+ onSaveBusinessMetadata: function() {
+ var that = this;
+ if (!this.validate()) {
+ return;
+ }
+ var nData = this.generateData();
+ if (this.actualCollection.length === 0 && _.isEmpty(nData)) {
+ this.onCancel();
+ return;
+ }
+ this.entityModel.saveBusinessMetadataEntity(this.guid, {
+ data: JSON.stringify(nData),
+ type: "POST",
+ success: function(data) {
+ Utils.notifySuccess({
+ content: "One or more Business Metadada attributes" + Messages.getAbbreviationMsg(false, 'editSuccessMessage')
+ });
+ that.entity.businessAttributes = data;
+ this.editMode = false;
+ that.fetchCollection();
+ that.onCancel();
+ },
+ complete: function(model, response) {
+ //that.hideLoader();
+ }
+ });
+ },
+ generateData: function() {
+ var finalObj = {};
+ this.collection.forEach(function(model) {
+ if (!model.has("addAttrButton")) {
+ var businessMetadataName = model.get("__internal_UI_businessMetadataName"),
+ modelObj = model.toJSON();
+ _.each(modelObj, function(o, k) {
+ if (k === "isNew" || k === "__internal_UI_businessMetadataName") {
+ delete modelObj[k];
+ return;
+ }
+ if (_.isObject(o) && o.value !== undefined) {
+ modelObj[k] = o.value;
+ }
+ })
+ if (businessMetadataName !== undefined) {
+ if (finalObj[businessMetadataName]) {
+ finalObj[businessMetadataName] = _.extend(finalObj[businessMetadataName], modelObj);
+ } else {
+ finalObj[businessMetadataName] = modelObj;
+ }
+ }
+ }
+ });
+ if (_.isEmpty(finalObj)) {
+ this.actualCollection.forEach(function(model) {
+ var businessMetadataName = model.get("__internal_UI_businessMetadataName");
+ if (businessMetadataName) {
+ finalObj[businessMetadataName] = {};
+ }
+ })
+ }
+ return finalObj;
+ },
+ createNameElement: function(options) {
+ var modelObj = { isNew: true };
+ this.collection.unshift(modelObj);
+ },
+ renderBusinessMetadata: function() {
+ var that = this,
+ li = ""
+ this.actualCollection.forEach(function(obj) {
+ var attrLi = "";
+ _.each(obj.attributes, function(val, key) {
+ if (key !== "__internal_UI_businessMetadataName") {
+ var newVal = val;
+ if (_.isObject(val) && !_.isUndefinedNull(val.value)) {
+ newVal = val.value;
+ if (newVal.length > 0 && val.typeName.indexOf("date") > -1) {
+ newVal = _.map(newVal, function(dates) {
+ return moment(dates).format("MM/DD/YYYY");
+ });
+ }
+ if (val.typeName === "date") {
+ newVal = moment(newVal).format("MM/DD/YYYY");
+ }
+
+ }
+ attrLi += "<tr><td>" + _.escape(key) + " (" + _.escape(val.typeName) + ")</td><td>" + _.escape(newVal) + "</td></tr>";
+ }
+ });
+ li += that.associateAttributePanel(obj, attrLi);
+ });
+ this.ui.businessMetadataTree.html(li);
+ },
+ associateAttributePanel: function(obj, tableBody) {
+ return '<div class="panel panel-default custom-panel expand_collapse_panel-icon no-border business-metadata-detail-attr">' +
+ '<div class="panel-heading" data-toggle="collapse" href="#' + _.escape(obj.get("__internal_UI_businessMetadataName")) + '" aria-expanded="true" style="width: 70%;">' +
+ '<h4 class="panel-title"> <a>' + _.escape(obj.get("__internal_UI_businessMetadataName")) + '</a></h4>' +
+ '<div class="btn-group pull-left"> <button type="button" title="Collapse"><i class="ec-icon fa"></i></button></div>' +
+ '</div>' +
+ '<div id="' + _.escape(obj.get("__internal_UI_businessMetadataName")) + '" class="panel-collapse collapse in">' +
+ '<div class="panel-body"><table class="table">' + tableBody + '</table></div>' +
+ '</div></div>';
+ },
+ onRender: function() {
+ this.panelOpenClose();
+ this.renderBusinessMetadata();
+ }
+ });
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js b/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js
index 9a40593..0a7d51a 100644
--- a/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js
+++ b/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js
@@ -51,6 +51,8 @@
events: function() {
var events = {};
events["click " + this.ui.noValueToggle] = function() {
+ this.showAllProperties = !this.showAllProperties;
+ this.ui.noValueToggle.attr("data-original-title", (this.showAllProperties ? "Hide" : "Show") + " empty values");
Utils.togglePropertyRelationshipTableEmptyValues({
"inputType": this.ui.noValueToggle,
"tableEl": this.ui.detailValue
@@ -66,6 +68,7 @@
initialize: function(options) {
_.extend(this, _.pick(options, 'entity', 'typeHeaders', 'attributeDefs', 'attributes', 'editEntity', 'guid', 'entityDefCollection', 'searchVent', 'fetchCollection'));
this.entityModel = new VEntity({});
+ this.showAllProperties = false;
},
bindEvents: function() {},
onRender: function() {
diff --git a/dashboardv2/public/js/views/search/QueryBuilderView.js b/dashboardv2/public/js/views/search/QueryBuilderView.js
index b6296d4..4be24f2 100644
--- a/dashboardv2/public/js/views/search/QueryBuilderView.js
+++ b/dashboardv2/public/js/views/search/QueryBuilderView.js
@@ -54,18 +54,8 @@
* @constructs
*/
initialize: function(options) {
- _.extend(this, _.pick(options,
- 'attrObj',
- 'value',
- 'typeHeaders',
- 'entityDefCollection',
- 'enumDefCollection',
- 'classificationDefCollection',
- 'tag',
- 'searchTableFilters',
- 'systemAttrArr'));
+ _.extend(this, _.pick(options, 'attrObj', 'value', 'typeHeaders', 'entityDefCollection', 'enumDefCollection', 'classificationDefCollection', 'businessMetadataDefCollection', 'tag', 'type', 'searchTableFilters', 'systemAttrArr', 'adminAttrFilters'));
this.attrObj = _.sortBy(this.attrObj, 'name');
- //this.systemAttrArr = _.sortBy(this.systemAttrArr, 'name');
this.filterType = this.tag ? 'tagFilters' : 'entityFilters';
},
bindEvents: function() {},
@@ -75,6 +65,9 @@
}
if (type === "string") {
obj.operators = ['=', '!=', 'contains', 'begins_with', 'ends_with'];
+ if (this.adminAttrFilters) {
+ obj.operators = obj.operators.concat(['like', 'in']);
+ }
}
if (type === "date") {
obj.operators = ['>', '<'];
@@ -289,12 +282,13 @@
_.extend(obj, this.getOperator(obj.type));
return obj;
}
+
if (this.isPrimitive(obj.type)) {
if (obj.type === "boolean") {
obj['input'] = 'select';
obj['values'] = ['true', 'false'];
}
- _.extend(obj, this.getOperator(obj.type));
+ _.extend(obj, this.getOperator(obj.type, false));
if (_.has(Enums.regex.RANGE_CHECK, obj.type)) {
obj.validation = {
min: Enums.regex.RANGE_CHECK[obj.type].min,
@@ -324,49 +318,96 @@
onRender: function() {
var that = this,
filters = [],
- isGroupView = false,
+ isGroupView = true,
placeHolder = '--Select Attribute--';
- if (this.attrObj.length > 0 && this.systemAttrArr.length > 0) {
- isGroupView = true;
- } else if (this.attrObj.length === 0 || this.systemAttrArr.length === 0) {
- isGroupView = false;
- }
- if (this.attrObj.length === 0) {
- placeHolder = '--Select System Attribute--';
- }
- if (this.value) {
- var rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters[this.filterType][(this.tag ? this.value.tag : this.value.type)], "formatDate": true });
- }
- _.each(this.attrObj, function(obj) {
- var type = that.tag ? 'Classification' : 'Entity';
- var returnObj = that.getObjDef(obj, rules_widgets, isGroupView, 'Select ' + type + ' Attribute');
- if (returnObj) {
- filters.push(returnObj);
+ var rules_widgets = null;
+ if (this.adminAttrFilters) {
+ var entityDef = this.entityDefCollection.fullCollection.find({ name: "__AtlasAuditEntry" }),
+ auditEntryAttributeDefs = null;
+ if (entityDef) {
+ auditEntryAttributeDefs = $.extend(true, {}, entityDef.get("attributeDefs")) || null;
}
- });
- var sortMap = {
- "__guid": 1,
- "__typeName": 2,
- "__timestamp": 3,
- "__modificationTimestamp": 4,
- "__createdBy": 5,
- "__modifiedBy": 6,
- "__isIncomplete": 7,
- "__state": 8,
- "__classificationNames": 9,
- "__propagatedClassificationNames": 10,
- "__labels": 11,
- "__customAttributes": 12,
- }
- this.systemAttrArr = _.sortBy(this.systemAttrArr, function(obj) {
- return sortMap[obj.name]
- })
- _.each(this.systemAttrArr, function(obj) {
- var returnObj = that.getObjDef(obj, rules_widgets, isGroupView, 'Select System Attribute', true);
- if (returnObj) {
- filters.push(returnObj);
+ if (auditEntryAttributeDefs) {
+ _.each(auditEntryAttributeDefs, function(attributes) {
+ var returnObj = that.getObjDef(attributes, rules_widgets);
+ if (returnObj) {
+ filters.push(returnObj);
+ }
+ });
}
- });
+ rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters ? this.searchTableFilters["adminAttrFilters"] : null, "formatDate": true });;
+ } else {
+ if (this.value) {
+ var rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters[this.filterType][(this.tag ? this.value.tag : this.value.type)], "formatDate": true });
+ }
+ _.each(this.attrObj, function(obj) {
+ var type = that.tag ? that.value.tag : that.value.type;
+ var returnObj = that.getObjDef(obj, rules_widgets, isGroupView, (type + ' Attribute'));
+ if (returnObj) {
+ filters.push(returnObj);
+ }
+ });
+ var sortMap = {
+ "__guid": 1,
+ "__typeName": 2,
+ "__timestamp": 3,
+ "__modificationTimestamp": 4,
+ "__createdBy": 5,
+ "__modifiedBy": 6,
+ "__isIncomplete": 7,
+ "__state": 8,
+ "__classificationNames": 9,
+ "__propagatedClassificationNames": 10,
+ "__labels": 11,
+ "__customAttributes": 12,
+ }
+ this.systemAttrArr = _.sortBy(this.systemAttrArr, function(obj) {
+ return sortMap[obj.name]
+ })
+ _.each(this.systemAttrArr, function(obj) {
+ var returnObj = that.getObjDef(obj, rules_widgets, isGroupView, 'System Attribute', true);
+ if (returnObj) {
+ filters.push(returnObj);
+ }
+ });
+ if (this.type) {
+ var pushBusinessMetadataFilter = function(sortedAttributes, businessMetadataKey) {
+ _.each(sortedAttributes, function(attrDetails) {
+ var returnObj = that.getObjDef(attrDetails, rules_widgets, isGroupView, "Business Attributes: " + businessMetadataKey);
+ if (returnObj) {
+ returnObj.id = businessMetadataKey + "." + returnObj.id;
+ returnObj.label = returnObj.label;
+ returnObj.data = { 'entityType': "businessMetadata" };
+ filters.push(returnObj);
+ }
+ });
+ };
+ if (this.value.type == "_ALL_ENTITY_TYPES") {
+ this.businessMetadataDefCollection.each(function(model) {
+ var sortedAttributes = model.get('attributeDefs');
+ sortedAttributes = _.sortBy(sortedAttributes, function(obj) {
+ return obj.name;
+ });
+ pushBusinessMetadataFilter(sortedAttributes, model.get('name'));
+ })
+
+ } else {
+ var entityDef = this.entityDefCollection.fullCollection.find({ name: this.value.type }),
+ businessMetadataAttributeDefs = null;
+ if (entityDef) {
+ businessMetadataAttributeDefs = entityDef.get("businessAttributeDefs");
+ }
+ if (businessMetadataAttributeDefs) {
+ _.each(businessMetadataAttributeDefs, function(attributes, key) {
+ var sortedAttributes = _.sortBy(attributes, function(obj) {
+ return obj.name;
+ });
+ pushBusinessMetadataFilter(sortedAttributes, key);
+ });
+ }
+ }
+ }
+ }
filters = _.uniq(filters, 'id');
if (filters && !_.isEmpty(filters)) {
this.ui.builder.queryBuilder({
@@ -402,6 +443,8 @@
{ type: '>=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
{ type: '<=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
{ type: 'contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ { type: 'like', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ { type: 'in', nb_inputs: 1, multiple: false, apply_to: ['string'] },
{ type: 'begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
{ type: 'ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
{ type: 'is_null', nb_inputs: false, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
diff --git a/dashboardv2/public/js/views/search/SearchLayoutView.js b/dashboardv2/public/js/views/search/SearchLayoutView.js
index 3cd0ab4..07ed112 100644
--- a/dashboardv2/public/js/views/search/SearchLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchLayoutView.js
@@ -90,10 +90,13 @@
* @constructs
*/
initialize: function(options) {
- _.extend(this, _.pick(options, 'value', 'typeHeaders', 'searchVent', 'entityDefCollection', 'enumDefCollection', 'classificationDefCollection', 'searchTableColumns', 'searchTableFilters', 'metricCollection'));
+ _.extend(this, _.pick(options, 'value', 'typeHeaders', 'searchVent', 'entityDefCollection', 'enumDefCollection', 'classificationDefCollection', 'businessMetadataDefCollection', 'searchTableColumns', 'searchTableFilters', 'metricCollection'));
this.type = "basic";
this.entityCountObj = _.first(this.metricCollection.toJSON());
- this.filterTypeSelected = [];
+ this.selectedFilter = {
+ 'basic': [],
+ 'dsl': []
+ }
var param = Utils.getUrlState.getQueryParams();
this.query = {
dsl: {
@@ -426,7 +429,9 @@
entityDefCollection: that.entityDefCollection,
enumDefCollection: that.enumDefCollection,
classificationDefCollection: that.classificationDefCollection,
- searchTableFilters: that.searchTableFilters
+ businessMetadataDefCollection: that.businessMetadataDefCollection,
+ searchTableFilters: that.searchTableFilters,
+
});
that.attrModal.on('ok', function(scope, e) {
that.okAttrFilterButton(e);
@@ -490,8 +495,9 @@
serviceArr.push(serviceType);
}
});
+
_.each(_.uniq(serviceArr), function(service) {
- serviceStr += '<li><div class="pretty p-switch p-fill"><input type="checkbox" class="pull-left" data-value="' + (service) + '" value="" ' + (_.contains(that.filterTypeSelected, service) ? "checked" : "") + '/><div class="state p-primary"><label>' + (service.toUpperCase()) + '</label></div></div></li>';
+ serviceStr += '<li><div class="pretty p-switch p-fill"><input type="checkbox" class="pull-left" data-value="' + (service) + '" value="" ' + (_.contains(that.selectedFilter[that.type], service) ? "checked" : "") + '/><div class="state p-primary"><label>' + (service.toUpperCase()) + '</label></div></div></li>';
});
var templt = serviceStr + '<hr class="hr-filter"/><div class="text-right"><div class="divider"></div><button class="btn btn-action btn-sm filterDone">Done</button></div>';
return templt;
@@ -500,6 +506,9 @@
var that = this;
var serviceTypeToBefiltered = (options && options.filterList);
var isTypeOnly = options && options.isTypeOnly;
+ if (this.selectedFilter[this.type].length) {
+ serviceTypeToBefiltered = this.selectedFilter[this.type];
+ }
this.ui.typeLov.empty();
var typeStr = '<option></option>',
tagStr = typeStr,
@@ -564,14 +573,14 @@
allowClear: true,
getFilterBox: this.getFilterBox.bind(this),
onFilterSubmit: function(options) {
- that.filterTypeSelected = options.filterVal;
+ that.selectedFilter[that.type] = options.filterVal;
that.renderTypeTagList({ "filterList": options.filterVal, isTypeOnly: true })
}
});
typeLovSelect2.on("select2:close", function() {
typeLovSelect2.trigger("hideFilter");
});
- if (typeLovSelect2 && serviceTypeToBefiltered) {
+ if (typeLovSelect2 && isTypeOnly) {
typeLovSelect2.select2('open').trigger("change", { 'manual': true });
}
if (that.setInitialEntityVal) {
@@ -778,7 +787,7 @@
}
},
clearSearchData: function() {
- this.filterTypeSelected = [];
+ this.selectedFilter[this.type] = [];
this.renderTypeTagList();
this.updateQueryObject();
this.ui.typeLov.val("").trigger("change");
diff --git a/dashboardv2/public/js/views/search/SearchQueryView.js b/dashboardv2/public/js/views/search/SearchQueryView.js
index 692a9df..69a35a5 100644
--- a/dashboardv2/public/js/views/search/SearchQueryView.js
+++ b/dashboardv2/public/js/views/search/SearchQueryView.js
@@ -52,7 +52,7 @@
* @constructs
*/
initialize: function(options) {
- _.extend(this, _.pick(options, 'value', 'entityDefCollection', 'typeHeaders', 'searchVent', 'enumDefCollection', 'classificationDefCollection', 'tag', 'searchTableFilters'));
+ _.extend(this, _.pick(options, 'value', 'entityDefCollection', 'typeHeaders', 'searchVent', 'enumDefCollection', 'classificationDefCollection', 'businessMetadataDefCollection', 'tag', 'searchTableFilters'));
this.bindEvents();
var that = this;
this.modal = new Modal({
@@ -82,13 +82,13 @@
});
},
onRender: function() {
- this.$('.fontLoader').show();
var obj = {
value: this.value,
searchVent: this.searchVent,
entityDefCollection: this.entityDefCollection,
enumDefCollection: this.enumDefCollection,
classificationDefCollection: this.classificationDefCollection,
+ businessMetadataDefCollection: this.businessMetadataDefCollection,
searchTableFilters: this.searchTableFilters,
typeHeaders: this.typeHeaders
}
diff --git a/dashboardv2/public/js/views/search/SearchResultLayoutView.js b/dashboardv2/public/js/views/search/SearchResultLayoutView.js
index ac78e89..2b41f92 100644
--- a/dashboardv2/public/js/views/search/SearchResultLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchResultLayoutView.js
@@ -147,7 +147,7 @@
* @constructs
*/
initialize: function(options) {
- _.extend(this, _.pick(options, 'value', 'guid', 'initialView', 'isTypeTagNotExists', 'classificationDefCollection', 'entityDefCollection', 'typeHeaders', 'searchVent', 'enumDefCollection', 'tagCollection', 'searchTableColumns', 'isTableDropDisable', 'fromView', 'glossaryCollection', 'termName'));
+ _.extend(this, _.pick(options, 'value', 'guid', 'initialView', 'isTypeTagNotExists', 'classificationDefCollection', 'entityDefCollection', 'typeHeaders', 'searchVent', 'enumDefCollection', 'tagCollection', 'searchTableColumns', 'isTableDropDisable', 'fromView', 'glossaryCollection', 'termName', 'businessMetadataDefCollection'));
this.entityModel = new VEntity();
this.searchCollection = new VSearchList();
this.limit = 25;
@@ -543,7 +543,6 @@
Globals.searchApiCallRef = this.searchCollection.fetch(apiObj);
}
}
-
},
tableRender: function(options) {
var that = this,
@@ -644,7 +643,6 @@
if (this.value && this.value.searchType === "basic" && this.searchTableColumns && (this.searchTableColumns[this.value.type] !== undefined)) {
columnToShow = this.searchTableColumns[this.value.type] == null ? [] : this.searchTableColumns[this.value.type];
}
-
col['Check'] = {
name: "selected",
label: "Select",
@@ -729,8 +727,6 @@
}
})
};
-
-
if (this.value && this.value.profileDBView) {
col['createTime'] = {
label: "Date Created",
@@ -749,7 +745,6 @@
}
}
if (this.value && !this.value.profileDBView) {
-
col['description'] = {
label: "Description",
cell: "String",
@@ -791,7 +786,23 @@
if (this.value && this.value.searchType === "basic") {
var def = this.entityDefCollection.fullCollection.find({ name: this.value.type }),
- systemAttr = [];
+ systemAttr = [],
+ businessMetadataAttr = [],
+ businessAttributes = {};
+ if (this.value.type == "_ALL_ENTITY_TYPES") {
+ this.businessMetadataDefCollection.each(function(model) {
+ var sortedAttributes = model.get('attributeDefs') || null,
+ name = model.get('name');
+ if (sortedAttributes) {
+ sortedAttributes = _.sortBy(sortedAttributes, function(obj) {
+ return obj.name;
+ });
+ businessAttributes[name] = $.extend(true, {}, sortedAttributes);
+ }
+ })
+ } else {
+ businessAttributes = def ? ($.extend(true, {}, def.get('businessAttributeDefs')) || null) : null;
+ }
if (def || Globals[this.value.type] || (
this.value.tag ?
Globals[this.value.tag] ?
@@ -806,6 +817,17 @@
systemAttr = (Globals[this.value.tag] || Globals[Enums.addOnClassification[0]]).attributeDefs;
}
attrObj = attrObj.concat(systemAttr);
+ if (businessAttributes) {
+ _.each(businessAttributes, function(businessMetadata, businessMetadataName) {
+ _.each(businessMetadata, function(attr, index) {
+ var attribute = attr;
+ attribute.isBusinessAttributes = true;
+ attribute.name = businessMetadataName + '.' + attribute.name;
+ businessMetadataAttr.push(attribute);
+ })
+ })
+ }
+ attrObj = attrObj.concat(businessMetadataAttr);
_.each(attrObj, function(obj, key) {
var key = obj.name,
isRenderable = _.contains(columnToShow, key),
@@ -820,7 +842,7 @@
return;
}
col[obj.name] = {
- label: Enums.systemAttributes[obj.name] ? Enums.systemAttributes[obj.name] : _.escape(obj.name).capitalize(),
+ label: Enums.systemAttributes[obj.name] ? Enums.systemAttributes[obj.name] : (_.escape(obj.isBusinessAttributes ? obj.name : obj.name.capitalize())),
cell: "Html",
headerCell: Backgrid.HeaderHTMLDecodeCell,
editable: false,
@@ -828,6 +850,7 @@
orderable: true,
sortable: isSortable,
renderable: isRenderable,
+ headerClassName: obj.isBusinessAttributes ? "no-capitalize" : "",
formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
fromRaw: function(rawValue, model) {
var modelObj = model.toJSON();
diff --git a/dashboardv2/public/js/views/site/Header.js b/dashboardv2/public/js/views/site/Header.js
index 4dc17a4..48279e4 100644
--- a/dashboardv2/public/js/views/site/Header.js
+++ b/dashboardv2/public/js/views/site/Header.js
@@ -35,27 +35,13 @@
globalSearch: "[data-id='globalSearch']",
clearGlobalSearch: "[data-id='clearGlobalSearch']",
signOut: "[data-id='signOut']",
+ administrator: "[data-id='administrator']",
uiSwitch: "[data-id='uiSwitch']"
},
events: function() {
var events = {};
events['click ' + this.ui.backButton] = function() {
- var queryParams = Utils.getUrlState.getQueryParams(),
- urlPath = "searchUrl";
- if (queryParams && queryParams.from) {
- if (queryParams.from == "classification") {
- urlPath = "tagUrl";
- } else if (queryParams.from == "glossary") {
- urlPath = "glossaryUrl";
- }
- }
- Utils.setUrl({
- url: Globals.saveApplicationState.tabState[urlPath],
- mergeBrowserUrl: false,
- trigger: true,
- updateTabState: true
- });
-
+ Utils.backButtonClick();
};
events['click ' + this.ui.clearGlobalSearch] = function() {
this.ui.globalSearch.val("");
@@ -82,6 +68,14 @@
}
window.location.href = path;
};
+ events['click ' + this.ui.administrator] = function() {
+ Utils.setUrl({
+ url: "#!/administrator",
+ mergeBrowserUrl: false,
+ trigger: true,
+ updateTabState: true
+ });
+ };
return events;
},
@@ -90,7 +84,7 @@
},
setSearchBoxWidth: function(options) {
var atlasHeaderWidth = this.$el.find(".atlas-header").width(),
- minusWidth = Utils.getUrlState.isDetailPage() ? 413 : 263;
+ minusWidth = (Utils.getUrlState.isDetailPage() || Utils.getUrlState.isBSDetail()) ? 413 : 263;
if (options && options.updateWidth) {
atlasHeaderWidth = options.updateWidth(atlasHeaderWidth);
}
diff --git a/dashboardv2/public/js/views/site/SideNavLayoutView.js b/dashboardv2/public/js/views/site/SideNavLayoutView.js
index e5552a5..bf82f98 100644
--- a/dashboardv2/public/js/views/site/SideNavLayoutView.js
+++ b/dashboardv2/public/js/views/site/SideNavLayoutView.js
@@ -116,7 +116,7 @@
that.$('.tabs').find('li a[aria-controls="tab-' + view + '"]').parents('li').addClass('active').siblings().removeClass('active');
that.$('.tab-content').find('div#tab-' + view).addClass('active').siblings().removeClass('active');
};
- if (Utils.getUrlState.isSearchTab() || Utils.getUrlState.isInitial()) {
+ if (Utils.getUrlState.isSearchTab() || Utils.getUrlState.isInitial() || Utils.getUrlState.isAdministratorTab()) {
activeTab({ "view": "search" });
} else if (Utils.getUrlState.isTagTab()) {
activeTab({ "view": "classification" });
@@ -134,7 +134,7 @@
}
activeTab({ "view": view });
}
- },
+ }
});
return SideNavLayoutView;
});
\ No newline at end of file