You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by pi...@apache.org on 2022/10/20 04:52:15 UTC
[atlas] branch branch-2.0 updated: ATLAS-4686 : UI improvements to support Atlas Relationship Search
This is an automated email from the ASF dual-hosted git repository.
pinal pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/branch-2.0 by this push:
new 88b2815b6 ATLAS-4686 : UI improvements to support Atlas Relationship Search
88b2815b6 is described below
commit 88b2815b67259fa6765ceec38353cb8cc099b09a
Author: Farhan Khan <fa...@freestoneinfotech.com>
AuthorDate: Tue Oct 18 16:16:30 2022 +0530
ATLAS-4686 : UI improvements to support Atlas Relationship Search
Signed-off-by: Pinal Shah <pi...@freestoneinfotech.com>
(cherry picked from commit cb0bde41d5b7a33e83d47e9f53aa24d53dd9a803)
---
dashboardv2/public/css/scss/common.scss | 4 +
dashboardv2/public/css/scss/override.scss | 41 +-
dashboardv2/public/css/scss/tab.scss | 2 +-
dashboardv2/public/css/scss/tag.scss | 2 +-
.../js/collection/VRelationshipSearchList.js | 58 ++
.../js/collection/VRelationshipSearchResultList.js | 87 +++
dashboardv2/public/js/main.js | 22 +-
dashboardv2/public/js/models/VRelationSearch.js | 54 ++
.../public/js/models/VRelationshipSearch.js | 55 ++
dashboardv2/public/js/router/Router.js | 78 +-
.../RelationshipDetailPageLayoutView_tmpl.html | 122 ++++
.../entity/EntityDetailTableLayoutView_tmpl.html | 6 +
.../RelationSearchDetailLayoutView_tmpl.html | 23 +
.../RelationSearchResultLayoutView_tmpl.html | 54 +-
.../templates/search/RelationshipSearch_tmpl.html | 43 ++
.../js/templates/search/SearchLayoutView_tmpl.html | 115 +--
dashboardv2/public/js/utils/CommonViewFunction.js | 45 +-
dashboardv2/public/js/utils/Enums.js | 2 +
dashboardv2/public/js/utils/Globals.js | 4 +-
dashboardv2/public/js/utils/UrlLinks.js | 16 +
dashboardv2/public/js/utils/Utils.js | 29 +
.../js/views/detail_page/DetailPageLayoutView.js | 2 +-
.../RelationshipDetailPageLayoutView.js | 207 ++++++
.../js/views/entity/EntityDetailTableLayoutView.js | 5 +-
.../public/js/views/search/QueryBuilderView.js | 10 +-
.../views/search/RelationSearchDetailLayoutView.js | 62 ++
.../js/views/search/RelationSearchLayoutView.js | 386 ++++++++++
.../views/search/RelationSearchResultLayoutView.js | 813 +++++++++++++++++++++
.../public/js/views/search/SearchLayoutView.js | 37 +-
.../public/js/views/search/SearchQueryView.js | 12 +-
.../js/views/search/save/SaveModalLayoutView.js | 4 +-
.../js/views/search/save/SaveSearchItemView.js | 14 +-
.../public/js/views/search/save/SaveSearchView.js | 79 +-
dashboardv2/public/js/views/site/Header.js | 2 +-
.../public/js/views/site/SideNavLayoutView.js | 2 +-
dashboardv3/public/css/scss/common.scss | 4 +
dashboardv3/public/css/scss/leftsidebar.scss | 4 +
.../js/collection/VRelationshipSearchList.js | 58 ++
.../js/collection/VRelationshipSearchResultList.js | 87 +++
dashboardv3/public/js/main.js | 20 +-
dashboardv3/public/js/models/VRelationSearch.js | 54 ++
.../public/js/models/VRelationshipSearch.js | 55 ++
dashboardv3/public/js/router/Router.js | 75 +-
.../RelationshipDetailPageLayoutView_tmpl.html | 125 ++++
.../entity/EntityDetailTableLayoutView_tmpl.html | 6 +
.../RelationSearchResultLayoutView_tmpl.html | 103 +++
.../search/SearchDefaultLayoutView_tmpl.html | 17 +
.../search/SearchFilterBrowseLayoutView_tmpl.html | 3 +
.../search/SearchResultLayoutView_tmpl.html | 2 +-
.../search/tree/RelationshipLayoutView_tmpl.html | 33 +
dashboardv3/public/js/utils/CommonViewFunction.js | 42 +-
dashboardv3/public/js/utils/Enums.js | 2 +
dashboardv3/public/js/utils/Globals.js | 4 +-
dashboardv3/public/js/utils/UrlLinks.js | 16 +
dashboardv3/public/js/utils/Utils.js | 23 +
.../js/views/detail_page/DetailPageLayoutView.js | 2 +-
.../RelationshipDetailPageLayoutView.js | 212 ++++++
.../js/views/entity/EntityDetailTableLayoutView.js | 5 +-
.../public/js/views/search/QueryBuilderView.js | 10 +-
.../views/search/RelationSearchResultLayoutView.js | 804 ++++++++++++++++++++
.../js/views/search/SearchDefaultLayoutView.js | 113 ++-
.../views/search/SearchFilterBrowseLayoutView.js | 15 +-
.../public/js/views/search/SearchQueryView.js | 12 +-
.../js/views/search/save/SaveModalLayoutView.js | 16 +-
.../search/tree/ClassificationTreeLayoutView.js | 1 +
.../search/tree/CustomFilterTreeLayoutView.js | 110 ++-
.../tree/RelationshipSearchTreeLayoutView.js | 300 ++++++++
67 files changed, 4643 insertions(+), 187 deletions(-)
diff --git a/dashboardv2/public/css/scss/common.scss b/dashboardv2/public/css/scss/common.scss
index 2fb6a3a79..60b272214 100644
--- a/dashboardv2/public/css/scss/common.scss
+++ b/dashboardv2/public/css/scss/common.scss
@@ -94,6 +94,10 @@
font-weight: bold;
}
}
+
+ .relationship-detailpage-panel {
+ width: 58% !important;
+ }
}
pre {
diff --git a/dashboardv2/public/css/scss/override.scss b/dashboardv2/public/css/scss/override.scss
index 7a14abf6d..99152587f 100644
--- a/dashboardv2/public/css/scss/override.scss
+++ b/dashboardv2/public/css/scss/override.scss
@@ -18,10 +18,10 @@
/* override.scss */
.tabs li.tab.active {
- border-bottom: 2px solid $color_keppel_approx;
+ border-bottom: 2px solid $white;
a {
- color: $color_keppel_approx;
+ color: $white;
}
}
@@ -622,4 +622,41 @@ div.columnmanager-dropdown-container {
ul {
list-style: disc
}
+}
+
+#r_searchLayoutView {
+ .nav-tabs {
+ border-bottom: 1px solid #38bb9b;
+
+ li {
+ text-align: center;
+ width: 50%;
+ font-size: 14px;
+
+ a:hover {
+ background-color: transparent !important;
+ border-color: transparent !important;
+ border: 1px solid #38bb9b !important;
+ }
+
+ a {
+ color: #38bb9b;
+ }
+ }
+
+ & li:first-child {
+ margin-left: 0px;
+ }
+
+ li.active>a {
+ background-color: transparent !important;
+ border-bottom-color: #323544 !important;
+ border: 1px solid #38bb9b;
+ color: #fff;
+ }
+
+ li.active>a:hover {
+ background-color: #323544 !important;
+ }
+ }
}
\ No newline at end of file
diff --git a/dashboardv2/public/css/scss/tab.scss b/dashboardv2/public/css/scss/tab.scss
index c164b4744..6e0c7a53d 100644
--- a/dashboardv2/public/css/scss/tab.scss
+++ b/dashboardv2/public/css/scss/tab.scss
@@ -119,7 +119,7 @@ ul.tabs li.tab {
a {
font-size: 14px;
font-weight: 600;
- color: $white;
+ color: $color_keppel_approx;
display: block;
text-decoration: none;
width: 100%;
diff --git a/dashboardv2/public/css/scss/tag.scss b/dashboardv2/public/css/scss/tag.scss
index c7bfb7e72..b62523747 100644
--- a/dashboardv2/public/css/scss/tag.scss
+++ b/dashboardv2/public/css/scss/tag.scss
@@ -169,7 +169,7 @@
border-color: $color_bali_hai_approx;
}
-.entityLink {
+.entityLink, .relationLink {
font-size: 16px;
}
diff --git a/dashboardv2/public/js/collection/VRelationshipSearchList.js b/dashboardv2/public/js/collection/VRelationshipSearchList.js
new file mode 100644
index 000000000..16d8b845d
--- /dev/null
+++ b/dashboardv2/public/js/collection/VRelationshipSearchList.js
@@ -0,0 +1,58 @@
+/**
+ * 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',
+ 'collection/BaseCollection',
+ 'models/VRelationshipSearch',
+ 'utils/UrlLinks'
+], function(require, BaseCollection, VRelationshipSearch, UrlLinks) {
+ 'use strict';
+ var VRelationshipSearchList = BaseCollection.extend(
+ //Prototypal attributes
+ {
+ url: UrlLinks.baseURL,
+
+ model: VRelationshipSearch,
+
+ initialize: function() {
+ this.modelName = 'VRelationshipSearch';
+ this.modelAttrName = 'results';
+ },
+ getRelationship: function(id, options) {
+ var url = UrlLinks.relationshipApiUrl(id);
+
+ options = _.extend({
+ contentType: 'application/json',
+ dataType: 'json'
+ }, options);
+
+ return this.constructor.nonCrudOperation.call(this, url, 'GET', options);
+ }
+ },
+ //Static Class Members
+ {
+ /**
+ * Table Cols to be passed to Backgrid
+ * UI has to use this as base and extend this.
+ *
+ */
+ tableCols: {}
+ }
+ );
+ return VRelationshipSearchList;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/collection/VRelationshipSearchResultList.js b/dashboardv2/public/js/collection/VRelationshipSearchResultList.js
new file mode 100644
index 000000000..3befb8593
--- /dev/null
+++ b/dashboardv2/public/js/collection/VRelationshipSearchResultList.js
@@ -0,0 +1,87 @@
+/**
+ * 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',
+ 'collection/BaseCollection',
+ 'models/VRelationSearch',
+ 'utils/UrlLinks'
+], function(require, BaseCollection, VRelationSearch, UrlLinks) {
+ 'use strict';
+ var VRelationshipSearchResultList = BaseCollection.extend(
+ //Prototypal attributes
+ {
+ url: UrlLinks.relationshipSearchApiUrl(),
+
+ model: VRelationSearch,
+
+ initialize: function(options) {
+ _.extend(this, options);
+ this.modelName = 'VRelationshipSearchResultList';
+ this.modelAttrName = '';
+ this.dynamicTable = false;
+ },
+ parseRecords: function(resp, options) {
+ this.queryType = resp.queryType;
+ this.queryText = resp.queryText;
+ this.referredEntities = resp.referredEntities;
+ if (resp.attributes) {
+ this.dynamicTable = true;
+ var entities = [];
+ _.each(resp.attributes.values, function(obj) {
+ var temp = {};
+ _.each(obj, function(val, index) {
+ var key = resp.attributes.name[index];
+ if (key == "__guid") {
+ key = "guid"
+ }
+ temp[key] = val;
+ });
+ entities.push(temp);
+ });
+ return entities;
+ } else if (resp.entities) {
+ this.dynamicTable = false;
+ return resp.entities ? resp.entities : [];
+ } else {
+ return [];
+ }
+ },
+ getBasicRearchResult: function(options) {
+ var url = UrlLinks.relationshipSearchApiUrl('basic');
+
+ options = _.extend({
+ contentType: 'application/json',
+ dataType: 'json',
+ }, options);
+ options.data = JSON.stringify(options.data);
+
+ return this.constructor.nonCrudOperation.call(this, url, 'POST', options);
+ }
+ },
+ //Static Class Members
+ {
+ /**
+ * Table Cols to be passed to Backgrid
+ * UI has to use this as base and extend this.
+ *
+ */
+ tableCols: {}
+ }
+ );
+ return VRelationshipSearchResultList;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/main.js b/dashboardv2/public/js/main.js
index 0994c1b02..87d11ac72 100644
--- a/dashboardv2/public/js/main.js
+++ b/dashboardv2/public/js/main.js
@@ -208,13 +208,14 @@ require(['App',
'utils/UrlLinks',
'collection/VEntityList',
'collection/VTagList',
+ 'collection/VRelationshipSearchList',
'utils/Enums',
'utils/Utils',
'utils/Overrides',
'bootstrap',
'd3',
'select2'
-], function(App, Router, Helper, CommonViewFunction, Globals, UrlLinks, VEntityList, VTagList, Enums, Utils) {
+], function(App, Router, Helper, CommonViewFunction, Globals, UrlLinks, VEntityList, VTagList, VRelationshipSearchList, Enums, Utils) {
var that = this;
this.asyncFetchCounter = 5 + (Enums.addOnEntities.length + 1);
// entity
@@ -238,6 +239,11 @@ require(['App',
this.businessMetadataDefCollection = new VEntityList();
this.businessMetadataDefCollection.url = UrlLinks.businessMetadataDefApiUrl();
this.businessMetadataDefCollection.modelAttrName = "businessMetadataDefs";
+ //relationship
+ this.relationshipDefCollection = new VRelationshipSearchList();
+ this.relationshipDefCollection.url = UrlLinks.relationshipDefApiUrl();
+ this.relationshipDefCollection.modelAttrName = "relationshipDefs";
+ this.relationshipEventAgg = new Backbone.Wreqr.EventAggregator();
App.appRouter = new Router({
entityDefCollection: this.entityDefCollection,
@@ -246,7 +252,9 @@ require(['App',
classificationDefCollection: this.classificationDefCollection,
metricCollection: this.metricCollection,
classificationAndMetricEvent: this.classificationAndMetricEvent,
- businessMetadataDefCollection: this.businessMetadataDefCollection
+ businessMetadataDefCollection: this.businessMetadataDefCollection,
+ relationshipDefCollection: this.relationshipDefCollection,
+ relationshipEventAgg: this.relationshipEventAgg
});
var startApp = function() {
@@ -387,6 +395,16 @@ require(['App',
startApp();
}
});
+ this.relationshipDefCollection.fetch({
+ async: true,
+ complete: function() {
+ that.relationshipDefCollection.fullCollection.comparator = function(model) {
+ return model.get('name').toLowerCase();
+ };
+ that.relationshipDefCollection.fullCollection.sort({ silent: true });
+ that.relationshipEventAgg.trigger("Relationship:Update");
+ }
+ });
CommonViewFunction.fetchRootEntityAttributes({
url: UrlLinks.rootEntityDefUrl(Enums.addOnEntities[0]),
entity: Enums.addOnEntities,
diff --git a/dashboardv2/public/js/models/VRelationSearch.js b/dashboardv2/public/js/models/VRelationSearch.js
new file mode 100644
index 000000000..6ce5b879f
--- /dev/null
+++ b/dashboardv2/public/js/models/VRelationSearch.js
@@ -0,0 +1,54 @@
+/**
+ * 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',
+ 'models/BaseModel',
+ 'utils/UrlLinks'
+], function(require, VBaseModel, UrlLinks) {
+ 'use strict';
+ var VRelationSearch = VBaseModel.extend({
+ urlRoot: UrlLinks.relationshipSearchApiUrl(),
+
+ defaults: {},
+
+ serverSchema: {},
+
+ idAttribute: 'id',
+
+ initialize: function() {
+ this.modelName = 'VRelationSearch';
+ },
+ toString: function() {
+ return this.get('name');
+ },
+ /*************************
+ * Non - CRUD operations
+ *************************/
+ getEntity: function(id, options) {
+ var url = UrlLinks.relationApiUrl({ guid: id });
+
+ options = _.extend({
+ contentType: 'application/json',
+ dataType: 'json'
+ }, options);
+
+ return this.constructor.nonCrudOperation.call(this, url, 'GET', options);
+ }
+ }, {});
+ return VRelationSearch;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/models/VRelationshipSearch.js b/dashboardv2/public/js/models/VRelationshipSearch.js
new file mode 100644
index 000000000..f981091ee
--- /dev/null
+++ b/dashboardv2/public/js/models/VRelationshipSearch.js
@@ -0,0 +1,55 @@
+/**
+ * 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',
+ 'models/BaseModel',
+ 'utils/UrlLinks'
+], function(require, VBaseModel, UrlLinks) {
+ 'use strict';
+ var VRelationshipSearch = VBaseModel.extend({
+
+ urlRoot: UrlLinks.relationshipSearchApiUrl(),
+
+ defaults: {},
+
+ serverSchema: {},
+
+ idAttribute: 'id',
+
+ initialize: function() {
+ this.modelName = 'VRelationshipSearch';
+ },
+ toString: function() {
+ return this.get('name');
+ },
+ /*************************
+ * Non - CRUD operations
+ *************************/
+
+ getRelationship: function(id, options) {
+ var url = UrlLinks.relationshipSearchApiUrl({ guid: id});
+ options = _.extend({
+ contentType: 'application/json',
+ dataType: 'json'
+ }, options);
+
+ return this.constructor.nonCrudOperation.call(this, url, 'GET', options);
+ }
+ }, {});
+ return VRelationshipSearch;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/router/Router.js b/dashboardv2/public/js/router/Router.js
index b3b0b961e..84e5f98e1 100644
--- a/dashboardv2/public/js/router/Router.js
+++ b/dashboardv2/public/js/router/Router.js
@@ -35,6 +35,9 @@ define([
// Search
"!/search": "commonAction",
"!/search/searchResult": "searchResult",
+ //Relation
+ "!/relationship": "relationshipSearch",
+ "!/relationship/relationshipSearchResult": "relationshipSearch",
// Tag
"!/tag": "commonAction",
"!/tag/tagAttribute/(*name)": "tagAttributePageLoad",
@@ -43,6 +46,8 @@ define([
"!/glossary/:id": "glossaryDetailPage",
// Details
"!/detailPage/:id": "detailPage",
+ //Relationship Detail Page
+ "!/relationshipDetailPage/:id": "relationshipDetailPage",
//Administrator page
'!/administrator': 'administrator',
'!/administrator/businessMetadata/:id': 'businessMetadataDetailPage',
@@ -52,7 +57,7 @@ define([
'*actions': 'defaultAction'
},
initialize: function(options) {
- _.extend(this, _.pick(options, 'entityDefCollection', 'typeHeaders', 'enumDefCollection', 'classificationDefCollection', 'metricCollection', 'classificationAndMetricEvent', 'businessMetadataDefCollection'));
+ _.extend(this, _.pick(options, 'entityDefCollection', 'typeHeaders', 'enumDefCollection', 'classificationDefCollection', 'metricCollection', 'classificationAndMetricEvent', 'businessMetadataDefCollection', 'relationshipDefCollection', 'relationshipEventAgg'));
this.showRegions();
this.bindCommonEvents();
this.listenTo(this, 'route', this.postRouteExecute, this);
@@ -71,7 +76,9 @@ define([
'glossaryCollection': this.glossaryCollection,
'metricCollection': this.metricCollection,
'classificationAndMetricEvent': this.classificationAndMetricEvent,
- 'businessMetadataDefCollection': this.businessMetadataDefCollection
+ 'businessMetadataDefCollection': this.businessMetadataDefCollection,
+ 'relationshipDefCollection': this.relationshipDefCollection,
+ 'relationshipEventAgg': this.relationshipEventAgg
}
this.ventObj = {
searchVent: this.searchVent,
@@ -84,7 +91,8 @@ define([
},
searchTableFilters: {
tagFilters: {},
- entityFilters: {}
+ entityFilters: {},
+ relationshipFilters: {}
}
}
},
@@ -187,6 +195,37 @@ define([
});
}
},
+ relationshipDetailPage: function(id) {
+ var that = this;
+ if (id) {
+ require(["views/site/Header", "views/detail_page/RelationshipDetailPageLayoutView", "views/site/SideNavLayoutView"], function(Header, RelationshipDetailPageLayoutView, SideNavLayoutView) {
+ var paramObj = Utils.getUrlState.getQueryParams(),
+ options = _.extend({}, that.preFetchedCollectionLists, that.sharedObj, that.ventObj);
+ that.renderViewIfNotExists(that.getHeaderOptions(Header));
+ that.renderViewIfNotExists({
+ view: App.rSideNav,
+ manualRender: function() {
+ this.view.currentView.selectTab();
+ },
+ render: function() {
+ return new SideNavLayoutView(options);
+ }
+ });
+
+ var dOptions = _.extend({ id: id, value: paramObj }, options);
+ that.renderViewIfNotExists({
+ view: App.rNContent,
+ viewName: "RelationshipDetailPageLayoutView",
+ manualRender: function() {
+ this.view.currentView.manualRender(dOptions);
+ },
+ render: function() {
+ return new RelationshipDetailPageLayoutView(dOptions);
+ }
+ });
+ });
+ }
+ },
tagAttributePageLoad: function(tagName) {
var that = this;
require([
@@ -265,6 +304,8 @@ define([
'views/search/SearchDetailLayoutView',
'collection/VTagList'
], function(Header, SideNavLayoutView, SearchDetailLayoutView, VTagList) {
+ //This below method is added to reset the internal tab to Entities
+ Utils.updateInternalTabState();
var paramObj = Utils.getUrlState.getQueryParams(),
options = _.extend({}, that.preFetchedCollectionLists, that.sharedObj, that.ventObj),
tag = new VTagList();
@@ -410,6 +451,8 @@ define([
'views/site/SideNavLayoutView',
'views/search/SearchDetailLayoutView',
], function(Header, SideNavLayoutView, SearchDetailLayoutView) {
+ //This below method is added to reset the internal tab to Entities
+ Utils.updateInternalTabState();
var paramObj = Utils.getUrlState.getQueryParams(),
options = _.extend({}, that.preFetchedCollectionLists, that.sharedObj, that.ventObj);
that.renderViewIfNotExists(that.getHeaderOptions(Header));
@@ -439,6 +482,35 @@ define([
}
});
},
+ relationshipSearch: function() {
+ var that = this;
+ require([
+ 'views/site/Header',
+ 'views/site/SideNavLayoutView',
+ 'views/search/RelationSearchDetailLayoutView',
+ ], function(Header, SideNavLayoutView, RelationSearchDetailLayoutView) {
+ var paramObj = Utils.getUrlState.getQueryParams(),
+ options = _.extend({}, that.preFetchedCollectionLists, that.sharedObj, that.ventObj);
+ that.renderViewIfNotExists(that.getHeaderOptions(Header));
+ that.renderViewIfNotExists({
+ view: App.rSideNav,
+ manualRender: function() {},
+ render: function() {
+ return new SideNavLayoutView(_.extend({ 'value' : paramObj } ,options));
+ }
+ });
+
+ if (Utils.getUrlState.isRelationTab()) {
+ App.rNContent.show(new RelationSearchDetailLayoutView(_.extend({ 'value': paramObj, 'initialView': (paramObj ? false : true) }, options)));
+ } else {
+ if (App.rNContent.currentView) {
+ App.rNContent.currentView.destroy();
+ } else {
+ App.rNContent.$el.empty();
+ }
+ }
+ });
+ },
defaultAction: function(actions) {
// We have no matching route, lets just log what the URL was
Utils.setUrl({
diff --git a/dashboardv2/public/js/templates/detail_page/RelationshipDetailPageLayoutView_tmpl.html b/dashboardv2/public/js/templates/detail_page/RelationshipDetailPageLayoutView_tmpl.html
new file mode 100644
index 000000000..504502165
--- /dev/null
+++ b/dashboardv2/public/js/templates/detail_page/RelationshipDetailPageLayoutView_tmpl.html
@@ -0,0 +1,122 @@
+<!--
+ * 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="relationshipDetail form-horizontal col-sm-12">
+ <h1 class="title">
+ <div data-id="entityIcon" class="entity-icon-box position-relative"></div>
+ <span data-id="title"></span>
+ </h1>
+ </div>
+ <div class="row">
+ <div class="col-sm-12 default-tab">
+ <ul class="nav nav-tabs" data-id="tab-list">
+ <li role="properties" class="tab active"><a href="#tab-details" aria-controls="tab-details" role="tab" data-toggle="tab">Properties</a></li>
+ </ul>
+ </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_otherProperties">
+ <div class="panel-group" id="accordion">
+ <div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="entity">
+ <div class="panel-heading relationship-detailpage-panel" data-toggle="collapse" href="#collapse4" aria-expanded="true">
+ <h4 class="panel-title">
+ <a>Technical properties</a>
+ </h4>
+ <div class="btn-group pull-left">
+ <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
+ </div>
+ </div>
+ <div id="collapse4" class="panel-collapse collapse in">
+ <div class="panel-body">
+ <div class="entity-detail-table">
+ <table class="table bold-key">
+ <tbody data-id="otherAttributes" class="hide-empty-value">
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="col-md-6 loader-row">
+ <div id="r_relationshipDetailTableLayoutView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ </div>
+ <div id="r_end1View">
+ <div class="panel-group" id="accordion">
+ <div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="entity">
+ <div class="panel-heading relationship-detailpage-panel" data-toggle="collapse" href="#collapse2" aria-expanded="false">
+ <h4 class="panel-title">
+ <a>End 1 </a>
+ </h4>
+ <div class="btn-group pull-left">
+ <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
+ </div>
+ </div>
+ <div id="collapse2" class="panel-collapse collapse">
+ <div class="panel-body">
+ <div class="entity-detail-table">
+ <table class="table bold-key">
+ <tbody data-id="relationshipEnd1" class="hide-empty-value">
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div id="r_end2View">
+ <div class="panel-group" id="accordion">
+ <div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="entity">
+ <div class="panel-heading relationship-detailpage-panel" data-toggle="collapse" href="#collapse3" aria-expanded="false">
+ <h4 class="panel-title">
+ <a>End 2 </a>
+ </h4>
+ <div class="btn-group pull-left">
+ <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
+ </div>
+ </div>
+ <div id="collapse3" class="panel-collapse collapse">
+ <div class="panel-body">
+ <div class="entity-detail-table">
+ <table class="table bold-key">
+ <tbody data-id="relationshipEnd2" class="hide-empty-value">
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/entity/EntityDetailTableLayoutView_tmpl.html b/dashboardv2/public/js/templates/entity/EntityDetailTableLayoutView_tmpl.html
index 3fe0e95e5..d83d2d717 100644
--- a/dashboardv2/public/js/templates/entity/EntityDetailTableLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/entity/EntityDetailTableLayoutView_tmpl.html
@@ -18,7 +18,11 @@
<div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="entity">
<div class="panel-heading" data-toggle="collapse" href="#collapse1" aria-expanded="true" style="width: 58%">
<h4 class="panel-title">
+ {{#ifCond isRelationshipDetailPage "!==" true}}
<a>Technical properties </a>
+ {{else}}
+ <a>Relationship properties </a>
+ {{/ifCond}}
</h4>
<div class="btn-group pull-left">
<button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
@@ -27,9 +31,11 @@
<div class="panel-actions">
<div class="pretty p-switch p-fill" style="margin-right: 20px">
<input type="checkbox" data-id="noValueToggle" title="Show empty values" />
+ {{#ifCond isRelationshipDetailPage "!==" true}}
<div class="state p-primary">
<label></label>
</div>
+ {{/ifCond}}
</div>
{{#ifCond editEntity "===" true}}
<button data-id="editButton" title="Edit Entity" class="btn btn-action btn-sm pull-right">Edit</button>
diff --git a/dashboardv2/public/js/templates/search/RelationSearchDetailLayoutView_tmpl.html b/dashboardv2/public/js/templates/search/RelationSearchDetailLayoutView_tmpl.html
new file mode 100644
index 000000000..39c86f94b
--- /dev/null
+++ b/dashboardv2/public/js/templates/search/RelationSearchDetailLayoutView_tmpl.html
@@ -0,0 +1,23 @@
+<!--
+ * 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="container-fluid">
+ <div class="row">
+ <div class="col-sm-custom">
+ <div id="r_relationSearchResultLayoutView"></div>
+ </div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/dashboardv3/public/js/templates/search/SearchResultLayoutView_tmpl.html b/dashboardv2/public/js/templates/search/RelationSearchResultLayoutView_tmpl.html
similarity index 58%
copy from dashboardv3/public/js/templates/search/SearchResultLayoutView_tmpl.html
copy to dashboardv2/public/js/templates/search/RelationSearchResultLayoutView_tmpl.html
index b16a4d28a..7e9eae3a1 100644
--- a/dashboardv3/public/js/templates/search/SearchResultLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/search/RelationSearchResultLayoutView_tmpl.html
@@ -20,9 +20,10 @@
<div class="fontLoader" style="z-index:999">
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
- <div class="ellipsis-with-margin" style="display: none;"><span class="searchResult" style=" font-size: 16px;"></span></div>
+ <div class="ellipsis-with-margin" style="display: none;"><span class="searchResult" style=" font-size: 16px;"></span>
+ </div>
<div class="searchTable">
- <div class="no-data" style="display: none;">
+ <div class="row no-data" style="display: none;">
<div class="position-relative thick-border">
<div style="padding-top: 20px; " class="table-responsive tableBorder">
<table class="table table-hover backgrid table-quickMenu">
@@ -35,47 +36,20 @@
</div>
</div>
</div>
- <div class="pagination-box clearfix row" style="display: none;{{#unless isSearchTab}}margin-top: 0px;{{/unless}}">
- <div class="form-group filter-box col-md-12" {{#if isSearchTab}} style="position: absolute;right: 0;top: -44px; padding: 0;width:auto" {{/if}}>
- <div class="pull-right inline-content-fr no-padding-left">
- {{#if isSearchTab}}
+ <div style="padding-top: 0px;" class="">
+ <div class="row form-group pagination-box filter-box" style="display: none;">
+ <div class="col-sm-12 inline-content-fr no-padding-left">
<div class="inline" data-id="colManager"></div>
- {{#if entityCreate}}
- <div class="inline"><button class="btn btn-action btn-sm" data-id="createEntity"><i class="fa fa-plus"></i> Create Entity</button></div>
- {{/if}}
- <div class="inline"><button title="Save as custom filter" class="btn btn-action btn-sm" data-id="saveFilter"><i class="fa fa-save"></i> Save Filter</button></div>
- {{/if}}
- <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>
- </div>
- {{#unless isGlossaryView}}
- <div class="inline">
- <a href="javascript:void(0)" class="multiSelectTerm assignTerm btn btn-action btn-sm" style="display:none" title="Assign Term" data-id="addAssignTerm"><i class="fa fa-plus"></i> Term</a>
- </div>
- {{/unless}}
- <div class="action-box pull-right inline-content-fr">
- <div class="inline" data-id="containerCheckBox" style="display: none;">
- <label class="checkbox-inline btn" for="historicalentities">
- <input type="checkbox" data-id="checkDeletedEntity" data-value="includeDE" id="historicalentities" />
- <b>Show historical entities</b></label>
- </div>
- <div class="inline" data-id="containerCheckBox" style="display: none;">
- <label class="checkbox-inline btn" for="subclassifications">
- <input type="checkbox" data-id="checkSubClassification" data-value="excludeSC" id="subclassifications" />
- <b>Exclude sub-classifications</b></label>
- </div>
- {{#ifCond fromView '!==' "classification"}}
- <div class="inline" data-id="containerCheckBox" style="display: none;">
- <label class="checkbox-inline btn" for="subtypes">
- <input type="checkbox" data-id="checkSubType" data-value="excludeST" id="subtypes" />
- <b>Exclude sub-types</b></label>
- </div>
- {{/ifCond}}
- </div>
</div>
</div>
- <div id="r_searchResultTableLayoutView" class="col-sm-12"></div>
- <div class="pagination-box searach-result-pagination col-sm-12 no-padding" style="display: none">
+ <div id="r_relationSearchResultTableLayoutView">
+ <h1><b>Relationship Search</b></h1>
+ <div class="relationLink" style="display:none">
+ <p class="relationLink">Search Atlas for existing relationships
+ </p>
+ </div>
+ </div>
+ <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>
diff --git a/dashboardv2/public/js/templates/search/RelationshipSearch_tmpl.html b/dashboardv2/public/js/templates/search/RelationshipSearch_tmpl.html
new file mode 100644
index 000000000..4081f81b1
--- /dev/null
+++ b/dashboardv2/public/js/templates/search/RelationshipSearch_tmpl.html
@@ -0,0 +1,43 @@
+<!--
+ * 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-group relationshipSearch-container">
+ <div class="form-group">
+ <div class="srchType clearfix">
+ <div class="label-wrapper row">
+ <div class="col-sm-12" style="margin: 10px 0px 10px 0px">
+ <button type="button" class="btn btn-action btn-md pull-right typeLOV" title="Refresh" data-id="refreshRelationBtn"><i class="fa fa-refresh"></i></button>
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="srchType">
+ <span class="srchTitle relationSearchTitle">Search By Relationship</span>
+ <div class="col-sm-10 no-padding">
+ <select data-id="relationshipLOV"></select>
+ </div>
+ <div class="col-sm-2 no-padding">
+ <button type="button" class="btn btn-action btn-md pull-right typeLOV" title="Relationship Attribute Filter" data-id="relationAttrFilter"><i class="fa fa-filter"></i></button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <button class="btn btn-action" data-id="clearRelationSearch">Clear</button>
+ <button type="button" class="btn btn-atlas pull-right" data-id="relationshipSearchBtn" disabled="disabled">Search</button>
+</div>
+<div class="">
+ <div class="col-sm-12 well relationshipSaveSearch" data-id="r_saveSearchRelationship"></div>
+</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html b/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
index 3bc3121f4..f049fa420 100644
--- a/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
@@ -15,67 +15,84 @@
* limitations under the License.
-->
<div class="row row-margin-bottom">
- <div class="col-sm-12" style="margin:15px 0px;">
+ <div class="col-sm-12" style="margin-top: 10px;">
<div class="row">
- <div class="col-sm-9" style="margin-top: 5px;">
- <span class="pull-left">Basic</span>
- <label class="switch pull-left">
- <input type="checkbox" class="switch-input" name="queryType" value="text" />
- <span class="switch-slider"></span>
- </label>
- <span class="pull-left">Advanced</span>
- <span class="advancedInfo" data-id="advancedInfo"><i class="fa fa-question-circle-o"></i></span>
- </div>
- <div class="col-sm-3 filter-btn-wrapper">
- <button type="button" class="btn btn-action btn-sm pull-right typeLOV" title="Refresh" data-id="refreshBtn"><i class="fa fa-refresh"></i></button>
+ <div>
+ <ul class="nav nav-tabs" data-id="tab-searchlist">
+ <li role="basic-search" class="tab basicSearch active"><a href="#tab-basicSearch" aria-controls="tab-basicSearch" role="tab" data-toggle="tab" aria-expanded="true">ENTITIES</a></li>
+ <li role="relationship-search" class="tab relationshipSearch"><a href="#tab-relationshipSearch" aria-controls="tab-relationshipSearch" role="tab" data-toggle="tab">RELATIONSHIPS</a></li>
+ </ul>
</div>
</div>
- </div>
- <div class="col-sm-12 form-group">
- <div class="form-group">
- <div class="srchType clearfix">
- <span class="srchTitle">Search By Type</span>
- <div class="">
- <div class="col-sm-10 no-padding typeFilter">
- <select data-id="typeLOV"></select>
+ <div class="tab-content">
+ <div id="tab-basicSearch" role="basic-search" class="tab-pane active animated fadeIn row">
+ <div class="searchToggleBtn-container" style="margin:15px 0px; font-size: 14px;">
+ <div class="row">
+ <div class="col-sm-9" style="margin-top: 5px;">
+ <span class="pull-left">Basic</span>
+ <label class="switch pull-left">
+ <input type="checkbox" class="switch-input" name="queryType" value="text" />
+ <span class="switch-slider"></span>
+ </label>
+ <span class="pull-left">Advanced</span>
+ <span class="advancedInfo" data-id="advancedInfo"><i class="fa fa-question-circle-o"></i></span>
+ </div>
+ <div class="col-sm-3 filter-btn-wrapper">
+ <button type="button" class="btn btn-action btn-md pull-right typeLOV" title="Refresh" data-id="refreshBtn"><i class="fa fa-refresh"></i></button>
+ </div>
</div>
- <div class="col-sm-2 no-padding typeFilterBtn">
- <button type="button" class="btn btn-action btn-md pull-right typeLOV active" title="Entity Attribute Filter" data-id="typeAttrFilter"><i class="fa fa-filter"></i></button>
+ </div>
+ <div class="form-group basicSearch-container">
+ <div class="form-group">
+ <div class="srchType clearfix">
+ <span class="srchTitle">Search By Type</span>
+ <div class="">
+ <div class="col-sm-10 no-padding typeFilter">
+ <select data-id="typeLOV"></select>
+ </div>
+ <div class="col-sm-2 no-padding typeFilterBtn">
+ <button type="button" class="btn btn-action btn-md pull-right typeLOV active" title="Entity Attribute Filter" data-id="typeAttrFilter"><i class="fa fa-filter"></i></button>
+ </div>
+ </div>
+ </div>
+ <div class="srchType tagBox clearfix">
+ <span class="srchTitle">Search By Classification</span>
+ <div>
+ <div class="col-sm-10 no-padding">
+ <select data-id="tagLOV"></select>
+ </div>
+ <div class="col-sm-2 no-padding">
+ <button type="button" class="btn btn-action btn-md pull-right active" title="Tag Attribute Filter" data-id="tagAttrFilter"><i class="fa fa-filter"></i></button>
+ </div>
+ </div>
+ </div>
+ <div class="srchType termBox clearfix">
+ <span class="srchTitle">Search By Term</span>
+ <div class="">
+ <div class="col-sm-12 no-padding">
+ <select data-id="termLOV"></select>
+ </div>
+ </div>
+ </div>
+ <div class="srchType">
+ <span class="srchTitle searchText">Search By Text</span>
+ <input type="text" class="form-control" data-id="searchInput" placeholder="Search by text" style="margin: 5px 0px;">
+ </div>
</div>
+ <button class="btn btn-action" data-id="clearSearch">Clear</button>
+ <button type="button" class="btn btn-atlas pull-right" data-id="searchBtn" disabled="disabled">Search</button>
</div>
- </div>
- <div class="srchType tagBox clearfix">
- <span class="srchTitle">Search By Classification</span>
+ <div id="searchResult"></div>
<div>
- <div class="col-sm-10 no-padding">
- <select data-id="tagLOV"></select>
- </div>
- <div class="col-sm-2 no-padding">
- <button type="button" class="btn btn-action btn-md pull-right active" title="Tag Attribute Filter" data-id="tagAttrFilter"><i class="fa fa-filter"></i></button>
- </div>
+ <div class="col-sm-12 well basicSaveSearch" data-id="r_saveSearchBasic"></div>
</div>
- </div>
- <div class="srchType termBox clearfix">
- <span class="srchTitle">Search By Term</span>
<div class="">
- <div class="col-sm-12 no-padding">
- <select data-id="termLOV"></select>
- </div>
+ <div class="col-sm-12 well advanceSaveSearch" data-id="r_saveSearchAdvance" style="display: none"></div>
</div>
</div>
- <div class="srchType">
- <span class="srchTitle searchText">Search By Text</span>
- <input type="text" class="form-control" data-id="searchInput" placeholder="Search by text" style="margin: 5px 0px;">
+ <div id="tab-relationshipSearch" role="relationship-search" class="tab-pane row">
+ <div class="relationshipSearch" data-id="r_relationshipSearch"></div>
</div>
</div>
- <button class="btn btn-action" data-id="clearSearch">Clear</button>
- <button type="button" class="btn btn-atlas pull-right" data-id="searchBtn" disabled="disabled">Search</button>
- </div>
- <div id="searchResult"></div>
- <div class="col-sm-12">
- <div class="col-sm-12 well basicSaveSearch" data-id="r_saveSearchBasic"></div>
- </div>
- <div class="col-sm-12">
- <div class="col-sm-12 well advanceSaveSearch" data-id="r_saveSearchAdvance" style="display: none"></div>
</div>
</div>
\ No newline at end of file
diff --git a/dashboardv2/public/js/utils/CommonViewFunction.js b/dashboardv2/public/js/utils/CommonViewFunction.js
index 4ce47a13d..f93b1788a 100644
--- a/dashboardv2/public/js/utils/CommonViewFunction.js
+++ b/dashboardv2/public/js/utils/CommonViewFunction.js
@@ -87,6 +87,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
showListCount = options.showListCount || true,
highlightString = options.highlightString,
formatStringVal = options.formatStringVal,
+ isRelationshipAttr = options.isRelationshipAttribute, //For relationshipDetailpage
numberFormat = options.numberFormat || _.numberFormatWithComma;
var table = "",
@@ -197,7 +198,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
valueOfArray.push('<span class="json-string">' + tmpVal + '</span>');
}
}
- } else if (_.isObject(inputOutputField) && !id) {
+ } else if ((_.isObject(inputOutputField) && (!id || isRelationshipAttr))) {
var attributesList = inputOutputField;
if (scope.typeHeaders && inputOutputField.typeName) {
var typeNameCategory = scope.typeHeaders.fullCollection.findWhere({ name: inputOutputField.typeName });
@@ -228,7 +229,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
valueOfArray.push(Utils.JSONPrettyPrint(attributesList, getValue));
}
}
- if (id && inputOutputField) {
+ if (id && inputOutputField && !isRelationshipAttr) {
var name = Utils.getName(inputOutputField);
if ((name === "-" || name === id) && !inputOutputField.attributes) {
var fetch = true;
@@ -305,10 +306,18 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
if (options.guidHyperLink === false) {
val = getValue(keyValue, key);
} else {
- val = '<a title="' + key + '" href="#!/detailPage/' + _.escape(keyValue) + '">' + getValue(keyValue, key) + '</a>';
+ if (isRelationshipAttr) {
+ val = '<a title="' + key + '" href="#!/detailPage/' + _.escape(keyValue) + '?from=relationshipSearch">' + getValue(keyValue, key) + '</a>';
+ } else {
+ val = '<a title="' + key + '" href="#!/detailPage/' + _.escape(keyValue) + '">' + getValue(keyValue, key) + '</a>';
+ }
}
} else {
- val = getValue(keyValue, key);
+ if (isRelationshipAttr && (key === "createTime" || key === "updateTime")) {
+ val = Utils.formatDate({ date: keyValue });
+ } else {
+ val = getValue(keyValue, key);
+ }
}
if (isTable) {
var value = val,
@@ -414,6 +423,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
value = Utils.getUrlState.getQueryParams();
var entityFilters = CommonViewFunction.attributeFilter.extractUrl({ "value": value.entityFilters, "formatDate": true }),
tagFilters = CommonViewFunction.attributeFilter.extractUrl({ "value": value.tagFilters, "formatDate": true }),
+ relationshipFilters = CommonViewFunction.attributeFilter.extractUrl({ "value": value.relationshipFilters, "formatDate": true }),
queryArray = [];
function objToString(filterObj) {
@@ -450,6 +460,14 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
}
queryArray.push(tagKeyValue);
}
+ if (value.relationshipName) {
+ var relationshipKeyValue = '<span class="key">Relationship:</span> <span class="value">' + _.escape(value.relationshipName) + '</span>';
+ if (relationshipFilters) {
+ var conditionForRealtionship = (relationshipFilters.rules && relationshipFilters.rules.length == 1) ? '' : 'AND';
+ relationshipKeyValue += ' <span class="operator">' + conditionForRealtionship + '</span> (<span class="operator">' + relationshipFilters.condition + '</span> (' + objToString(relationshipFilters) + '))';
+ }
+ queryArray.push(relationshipKeyValue);
+ }
if (value.term) {
var tagKeyValue = '<span class="key">Term:</span> <span class="value">' + _.escape(value.term) + '</span>';
queryArray.push(tagKeyValue);
@@ -478,7 +496,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
if (!_.isUndefinedNull(val)) {
if (k == "attributes") {
val = val.split(',');
- } else if (_.contains(["tagFilters", "entityFilters"], k)) {
+ } else if (_.contains(["tagFilters", "entityFilters", "relationshipFilters"], k)) {
val = CommonViewFunction.attributeFilter.generateAPIObj(val);
} else if (_.contains(["includeDE", "excludeST", "excludeSC"], k)) {
val = val ? false : true;
@@ -503,6 +521,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
var value = options.value,
classificationDefCollection = options.classificationDefCollection,
entityDefCollection = options.entityDefCollection,
+ relationshipDefCollection = options.relationshipDefCollection,
obj = {};
if (value) {
_.each(Enums.extractFromUrlForSearch, function(svalue, skey) {
@@ -550,6 +569,22 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
}
}
val = CommonViewFunction.attributeFilter.generateUrl({ "value": val, "attributeDefs": attributeDefs });
+ } else if (k == "relationshipFilters") {
+ if (relationshipDefCollection) {
+ var relationshipDef = relationshipDefCollection.fullCollection.findWhere({ 'name': value[skey].relationshipName }),
+ attributeDefs = [];
+ if (relationshipDef) {
+ attributeDefs = Utils.getNestedSuperTypeObj({
+ collection: relationshipDefCollection,
+ attrMerge: true,
+ data: relationshipDef.toJSON()
+ });
+ }
+ if (Globals[value[skey].relationshipName]) {
+ attributeDefs = Globals[value[skey].relationshipName].attributeDefs;
+ }
+ }
+ val = CommonViewFunction.attributeFilter.generateUrl({ "value": val, "attributeDefs": attributeDefs });
} else if (_.contains(["includeDE", "excludeST", "excludeSC"], k)) {
val = val ? false : true;
}
diff --git a/dashboardv2/public/js/utils/Enums.js b/dashboardv2/public/js/utils/Enums.js
index ee80313c2..00bbe103d 100644
--- a/dashboardv2/public/js/utils/Enums.js
+++ b/dashboardv2/public/js/utils/Enums.js
@@ -103,6 +103,7 @@ define(["require", "backbone"], function(require) {
"searchParameters": {
"pageLimit": "limit",
"type": "typeName",
+ "relationshipName": "relationshipName",
"tag": "classification",
"query": "query",
"pageOffset": "offset",
@@ -111,6 +112,7 @@ define(["require", "backbone"], function(require) {
"excludeSC": "includeSubClassifications",
"tagFilters": "tagFilters",
"entityFilters": "entityFilters",
+ "relationshipFilters": "relationshipFilters",
"attributes": "attributes",
"term": "termName"
},
diff --git a/dashboardv2/public/js/utils/Globals.js b/dashboardv2/public/js/utils/Globals.js
index d2ce1a90f..0733f9424 100644
--- a/dashboardv2/public/js/utils/Globals.js
+++ b/dashboardv2/public/js/utils/Globals.js
@@ -33,7 +33,8 @@ define(["require", "underscore"], function(require, _) {
searchUrl: "#!/search",
glossaryUrl: "#!/glossary",
administratorUrl: "#!/administrator",
- debugMetricsUrl: "#!/debugMetrics"
+ debugMetricsUrl: "#!/debugMetrics",
+ relationUrl: '#!/relationship'
},
detailPageState: {}
};
@@ -57,6 +58,7 @@ define(["require", "underscore"], function(require, _) {
Globals.isLineageOnDemandEnabled = false;
Globals.lineageNodeCount = 3;
Globals.lineageDepth = 3;
+ Globals.fromRelationshipSearch = false;
return Globals;
});
\ No newline at end of file
diff --git a/dashboardv2/public/js/utils/UrlLinks.js b/dashboardv2/public/js/utils/UrlLinks.js
index 243b459be..8cdda1e16 100644
--- a/dashboardv2/public/js/utils/UrlLinks.js
+++ b/dashboardv2/public/js/utils/UrlLinks.js
@@ -43,6 +43,9 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
enumDefApiUrl: function(name) {
return this.getDefApiUrl('enum', name);
},
+ relationshipDefApiUrl: function() {
+ return this.getDefApiUrl('relationship', name);
+ },
metricsApiUrl: function() {
return this.baseUrl + '/admin/metrics'
},
@@ -106,6 +109,16 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
return entitiesUrl += '?minExtInfo=' + (minExtInfo);
}
},
+ relationApiUrl: function(options) {
+ var relationsUrl = this.baseUrlV2 + '/relationship';
+ if (options) {
+ var guid = options.guid,
+ name = options.name;
+ if (guid)
+ relationsUrl += '/guid/' + guid;
+ }
+ return relationsUrl;
+ },
entityLabelsAPIUrl: function(guid) {
return this.entitiesApiUrl({ guid: guid }) + "/labels";
},
@@ -178,6 +191,9 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
return relationshipUrl
}
},
+ relationshipSearchApiUrl: function() {
+ return this.baseUrlV2 + '/search/relations';
+ },
schemaApiUrl: function(guid) {
var lineageUrl = this.baseUrl + '/lineage';
if (guid) {
diff --git a/dashboardv2/public/js/utils/Utils.js b/dashboardv2/public/js/utils/Utils.js
index eb0588903..a83f3c17c 100644
--- a/dashboardv2/public/js/utils/Utils.js
+++ b/dashboardv2/public/js/utils/Utils.js
@@ -343,6 +343,8 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
urlUpdate['administratorUrl'] = options.url;
} else if (Utils.getUrlState.isDebugMetricsTab(options.url)) {
urlUpdate['debugMetricsUrl'] = options.url;
+ } else if (Utils.getUrlState.isRelationTab(options.url)) {
+ urlUpdate['relationUrl'] = options.url;
}
$.extend(Globals.saveApplicationState.tabState, urlUpdate);
}
@@ -388,6 +390,12 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
matchString: "search"
});
},
+ isRelationTab: function(url) {
+ return this.checkTabUrl({
+ url: url,
+ matchString: "relationship"
+ });
+ },
isAdministratorTab: function(url) {
return this.checkTabUrl({
url: url,
@@ -412,6 +420,12 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
matchString: "detailPage"
});
},
+ isRelationshipDetailPage: function(url) {
+ return this.checkTabUrl({
+ url: url,
+ matchString: "relationshipDetailPage"
+ });
+ },
getLastValue: function() {
return this.getQueryUrl().lastValue;
},
@@ -572,6 +586,9 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
urlPath = "administratorUrl";
}
}
+ if (Globals.fromRelationshipSearch) {
+ urlPath = 'relationUrl';
+ }
Utils.setUrl({
url: Globals.saveApplicationState.tabState[urlPath],
mergeBrowserUrl: false,
@@ -1284,5 +1301,17 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
}
//-----------------------------------------END---------------------//
+ Utils.updateInternalTabState = function() {
+ var tabActive = "",
+ paramObj = Utils.getUrlState.getQueryParams();
+ if (Utils.getUrlState.isSearchTab()) {
+ tabActive = "basic-search";
+ }
+ if (Utils.getUrlState.isDetailPage() && paramObj && paramObj.from === "relationshipSearch") {
+ tabActive = "relationship-search";
+ }
+ $('.nav.nav-tabs').find('[role="' + tabActive + '"]').addClass('active').siblings().removeClass('active');
+ $('.tab-content').find('[role="' + tabActive + '"]').addClass('active').siblings().removeClass('active');
+ }
return Utils;
});
diff --git a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
index bb629b4e4..73293507c 100644
--- a/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
+++ b/dashboardv2/public/js/views/detail_page/DetailPageLayoutView.js
@@ -440,7 +440,7 @@ define(['require',
this.updateTab();
},
onDestroy: function() {
- if (!Utils.getUrlState.isDetailPage()) {
+ if (!Utils.getUrlState.isDetailPage() && !Utils.getUrlState.isRelationshipDetailPage()) {
$('body').removeClass("detail-page");
}
},
diff --git a/dashboardv2/public/js/views/detail_page/RelationshipDetailPageLayoutView.js b/dashboardv2/public/js/views/detail_page/RelationshipDetailPageLayoutView.js
new file mode 100644
index 000000000..6f5aedb76
--- /dev/null
+++ b/dashboardv2/public/js/views/detail_page/RelationshipDetailPageLayoutView.js
@@ -0,0 +1,207 @@
+/**
+ * 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/detail_page/RelationshipDetailPageLayoutView_tmpl',
+ 'utils/Utils',
+ 'utils/CommonViewFunction',
+ 'utils/Globals',
+ 'utils/Enums',
+ 'utils/Messages',
+ 'utils/UrlLinks',
+ 'collection/VEntityList'
+], function(require, Backbone, RelationshipDetailPageLayoutView, Utils, CommonViewFunction, Globals, Enums, Messages, UrlLinks, VEntityList) {
+ 'use strict';
+
+ var RelationshipDetailPageLayoutView = Backbone.Marionette.LayoutView.extend(
+ /** @lends DetailPageLayoutView */
+ {
+ _viewName: 'RelationshipDetailPageLayoutView',
+
+ template: RelationshipDetailPageLayoutView,
+
+ /** Layout sub regions */
+ regions: {
+ RRelationshipDetailTableLayoutView: "#r_relationshipDetailTableLayoutView"
+ },
+ /** ui selector cache */
+ ui: {
+ title: '[data-id="title"]',
+ entityIcon: '[data-id="entityIcon"]',
+ relationshipEnd1: '[data-id="relationshipEnd1"]',
+ relationshipEnd2: '[data-id="relationshipEnd2"]',
+ otherAttributes: '[data-id="otherAttributes"]'
+ },
+ templateHelpers: function() {},
+ /** ui events hash */
+ events: function() {
+ var events = {};
+ return events;
+ },
+ /**
+ * intialize a new DetailPageLayoutView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, _.pick(options, 'value', 'collection', 'id', 'relationshipDefCollection', 'searchVent'));
+ $('body').addClass("detail-page");
+ this.collection = new VEntityList([], {});
+ this.collection.url = UrlLinks.relationApiUrl({ guid: this.id, minExtInfo: true });
+ this.fetchCollection();
+ },
+ bindEvents: function() {
+ var that = this;
+ this.listenTo(this.collection, 'reset', function() {
+ this.relationshipObject = this.collection.first().toJSON();
+ var collectionJSON = this.relationshipObject.relationship,
+ name = collectionJSON ? Utils.getName(collectionJSON) : "";
+ if (collectionJSON) {
+ this.readOnly = Enums.entityStateReadOnly[collectionJSON.status];
+ if (name && collectionJSON.typeName) {
+ name = name + ' (' + _.escape(collectionJSON.typeName) + ')';
+ }
+ if (this.readOnly) {
+ this.$el.addClass('readOnly');
+ } else {
+ this.$el.removeClass('readOnly');
+ }
+ if (name) {
+ this.ui.title.show();
+ var titleName = '<span>' + name + '</span>';
+ if (this.readOnly) {
+ titleName += '<button title="Deleted" class="btn btn-action btn-md deleteBtn"><i class="fa fa-trash"></i> Deleted</button>';
+ }
+ if (this.readOnly) {
+ this.ui.entityIcon.addClass('disabled');
+ } else {
+ this.ui.entityIcon.removeClass('disabled');
+ }
+ this.ui.title.html(titleName);
+ var entityData = _.extend({}, collectionJSON),
+ img = this.readOnly ? '<img src="/img/entity-icon/disabled/table.png"/>' : '<img src="/img/entity-icon/table.png"/>';
+ this.ui.entityIcon.attr('title', _.escape(collectionJSON.typeName)).html(img);
+ } else {
+ this.ui.title.hide();
+ }
+ }
+ this.hideLoader();
+ var obj = {
+ entity: collectionJSON,
+ guid: this.id,
+ entityName: name,
+ fetchCollection: this.fetchCollection.bind(that),
+ searchVent: this.searchVent,
+ attributeDefs: (function() {
+ return that.getEntityDef(collectionJSON);
+ })(),
+ isRelationshipDetailPage: true
+ }
+ this.renderRelationshipDetailTableLayoutView(obj);
+ this.ui.relationshipEnd1.empty().html(this.renderRelationAttributesDetails({
+ scope: this,
+ valueObject: collectionJSON.end1,
+ isRelationshipAttribute: true,
+ guidHyperLink: true
+ }));
+ this.ui.relationshipEnd2.empty().html(this.renderRelationAttributesDetails({
+ scope: this,
+ valueObject: collectionJSON.end2,
+ isRelationshipAttribute: true,
+ guidHyperLink: true
+ }));
+ this.ui.otherAttributes.empty().html(this.renderRelationAttributesDetails({
+ scope: this,
+ valueObject: _.pick(collectionJSON, 'createTime', 'createdBy', 'blockedPropagatedClassifications', 'guid', 'label', 'propagateTags', 'propagatedClassifications', 'provenanceType', 'status', 'updateTime', 'updatedBy', 'version'),
+ isRelationshipAttribute: true,
+ guidHyperLink: false
+ }));
+ }, this);
+ this.listenTo(this.collection, 'error', function(model, response) {
+ this.$('.fontLoader-relative').removeClass('show');
+ if (response.responseJSON) {
+ Utils.notifyError({
+ content: response.responseJSON.errorMessage || response.responseJSON.error
+ });
+ }
+ }, this);
+ },
+ onRender: function() {
+ var that = this;
+ this.bindEvents();
+ Utils.showTitleLoader(this.$('.page-title .fontLoader'), this.$('.relationshipDetail'));
+ this.$('.fontLoader-relative').addClass('show'); // to show tab loader
+ },
+ manualRender: function(options) {
+ if (options) {
+ var oldId = this.id;
+ _.extend(this, _.pick(options, 'value', 'id'));
+ if (this.id !== oldId) {
+ this.collection.url = UrlLinks.relationApiUrl({ guid: this.id, minExtInfo: true });
+ this.fetchCollection();
+ }
+ }
+ },
+ onDestroy: function() {
+ if (!Utils.getUrlState.isRelationshipDetailPage() && !Utils.getUrlState.isDetailPage()) {
+ $('body').removeClass("detail-page");
+ }
+ },
+ fetchCollection: function() {
+ this.collection.fetch({ reset: true });
+ if (this.searchVent) {
+ this.searchVent.trigger('relationshipList:refresh');
+ }
+ },
+ getEntityDef: function(entityObj) {
+ if (this.activeEntityDef) {
+ var data = this.activeEntityDef.toJSON();
+ var attributeDefs = Utils.getNestedSuperTypeObj({
+ data: data,
+ attrMerge: true,
+ collection: this.relationshipDefCollection
+ });
+ return attributeDefs;
+ } else {
+ return [];
+ }
+ },
+ hideLoader: function() {
+ Utils.hideTitleLoader(this.$('.page-title .fontLoader'), this.$('.relationshipDetail'));
+ },
+ showLoader: function() {
+ Utils.showTitleLoader(this.$('.page-title .fontLoader'), this.$('.relationshipDetail'));
+ },
+ renderRelationshipDetailTableLayoutView: function(obj) {
+ var that = this;
+ require(['views/entity/EntityDetailTableLayoutView'], function(EntityDetailTableLayoutView) {
+ that.RRelationshipDetailTableLayoutView.show(new EntityDetailTableLayoutView(obj));
+ });
+ },
+ renderRelationAttributesDetails: function(options) {
+ var table = CommonViewFunction.propertyTable({
+ scope: options.scope,
+ valueObject: options.valueObject,
+ isRelationshipAttribute: options.isRelationshipAttribute,
+ guidHyperLink: options.guidHyperLink
+ });
+ return table;
+ }
+ });
+ return RelationshipDetailPageLayoutView;
+});
\ 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 5eee4d711..eb4647c2c 100644
--- a/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js
+++ b/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js
@@ -34,7 +34,8 @@ define(['require',
templateHelpers: function() {
return {
- editEntity: this.editEntity
+ editEntity: this.editEntity,
+ isRelationshipDetailPage: this.isRelationshipDetailPage
};
},
@@ -66,7 +67,7 @@ define(['require',
* @constructs
*/
initialize: function(options) {
- _.extend(this, _.pick(options, 'entity', 'typeHeaders', 'attributeDefs', 'attributes', 'editEntity', 'guid', 'entityDefCollection', 'searchVent', 'fetchCollection'));
+ _.extend(this, _.pick(options, 'entity', 'typeHeaders', 'attributeDefs', 'attributes', 'editEntity', 'guid', 'entityDefCollection', 'searchVent', 'fetchCollection', 'isRelationshipDetailPage'));
this.entityModel = new VEntity({});
this.showAllProperties = false;
},
diff --git a/dashboardv2/public/js/views/search/QueryBuilderView.js b/dashboardv2/public/js/views/search/QueryBuilderView.js
index 983f8b759..0446f424a 100644
--- a/dashboardv2/public/js/views/search/QueryBuilderView.js
+++ b/dashboardv2/public/js/views/search/QueryBuilderView.js
@@ -56,10 +56,13 @@ define(['require',
* @constructs
*/
initialize: function(options) {
- _.extend(this, _.pick(options, 'attrObj', 'value', 'typeHeaders', 'entityDefCollection', 'enumDefCollection', 'classificationDefCollection', 'businessMetadataDefCollection', 'tag', 'type', 'searchTableFilters', 'systemAttrArr', 'adminAttrFilters'));
+ _.extend(this, _.pick(options, 'attrObj', 'value', 'typeHeaders', 'entityDefCollection', 'enumDefCollection', 'classificationDefCollection', 'businessMetadataDefCollection', 'tag', 'type', 'searchTableFilters', 'systemAttrArr', 'adminAttrFilters', 'relationship'));
this.attrObj = _.sortBy(this.attrObj, 'name');
this.filterType = this.tag ? 'tagFilters' : 'entityFilters';
this.defaultRange = "Last 7 Days";
+ if(this.relationship){
+ this.filterType = 'relationshipFilters';
+ }
this.dateRangesMap = {
'Today': [moment(), moment()],
'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
@@ -403,10 +406,13 @@ define(['require',
rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters ? this.searchTableFilters["adminAttrFilters"] : null, "formatDate": true });;
} else {
if (this.value) {
- rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters[this.filterType][(this.tag ? this.value.tag : this.value.type)], "formatDate": true });
+ rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters[this.filterType][(this.tag ? this.value.tag : this.value.type) || this.value.relationshipName], "formatDate": true });
}
_.each(this.attrObj, function(obj) {
var type = that.tag ? that.value.tag : that.value.type;
+ if (that.value.relationshipName) {
+ type = that.value.relationshipName;
+ }
var returnObj = that.getObjDef(obj, rules_widgets, isGroupView, (type + ' Attribute'));
if (returnObj) {
filters.push(returnObj);
diff --git a/dashboardv2/public/js/views/search/RelationSearchDetailLayoutView.js b/dashboardv2/public/js/views/search/RelationSearchDetailLayoutView.js
new file mode 100644
index 000000000..2af3b8ce8
--- /dev/null
+++ b/dashboardv2/public/js/views/search/RelationSearchDetailLayoutView.js
@@ -0,0 +1,62 @@
+/**
+ * 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/search/RelationSearchDetailLayoutView_tmpl',
+], function(require, Backbone, RelationSearchDetailLayoutViewTmpl) {
+ 'use strict';
+
+ var RelationSearchDetailLayoutView = Backbone.Marionette.LayoutView.extend(
+ /** @lends RelationSearchDetailLayoutView */
+ {
+ _viewName: 'RelationSearchDetailLayoutView',
+
+ template: RelationSearchDetailLayoutViewTmpl,
+
+ /** Layout sub regions */
+ regions: {
+ RRelationSearchResultLayoutView: "#r_relationSearchResultLayoutView"
+ },
+
+ /** ui selector cache */
+ ui: {},
+ /** ui events hash */
+ events: function() {},
+ /**
+ * intialize a new RelationSearchDetailLayoutView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, options);
+ },
+ bindEvents: function() {},
+ onRender: function() {
+ this.renderRelationSearchResultLayoutView();
+ },
+ renderRelationSearchResultLayoutView: function() {
+ var that = this;
+ require(['views/search/RelationSearchResultLayoutView'], function(RelationSearchResultLayoutView) {
+ if (that.RRelationSearchResultLayoutView) {
+ that.RRelationSearchResultLayoutView.show(new RelationSearchResultLayoutView(that.options));
+ }
+ });
+ }
+ });
+ return RelationSearchDetailLayoutView;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/search/RelationSearchLayoutView.js b/dashboardv2/public/js/views/search/RelationSearchLayoutView.js
new file mode 100644
index 000000000..18d6b7694
--- /dev/null
+++ b/dashboardv2/public/js/views/search/RelationSearchLayoutView.js
@@ -0,0 +1,386 @@
+/**
+ * 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/search/RelationshipSearch_tmpl',
+ 'utils/Utils',
+ 'utils/UrlLinks',
+ 'utils/Globals',
+ 'utils/Enums',
+ 'collection/VSearchList',
+ 'utils/CommonViewFunction',
+ 'modules/Modal'
+], function(require, Backbone, RelationshipSearchViewTmpl, Utils, UrlLinks, Globals, Enums, VSearchList, CommonViewFunction, Modal) {
+ 'use strict';
+
+ var RelationshipSearchLayoutView = Backbone.Marionette.LayoutView.extend(
+ /** @lends SearchLayoutView */
+ {
+ _viewName: 'RelationshipSearchLayoutView',
+
+ template: RelationshipSearchViewTmpl,
+
+ /** Layout sub regions */
+ regions: {
+ RSaveSearchRelationship: "[data-id='r_saveSearchRelationship']"
+ },
+
+ /** ui selector cache */
+ ui: {
+ searchBtn: '[data-id="relationshipSearchBtn"]',
+ clearSearch: '[data-id="clearRelationSearch"]',
+ relationshipLov: '[data-id="relationshipLOV"]',
+ relationshipAttrFilter: '[data-id="relationAttrFilter"]',
+ refreshBtn: '[data-id="refreshRelationBtn"]'
+ },
+
+ /** ui events hash */
+ events: function() {
+ var events = {},
+ that = this;
+ events["click " + this.ui.searchBtn] = 'findSearchResult';
+ events["change " + this.ui.relationshipLov] = 'checkForButtonVisiblity';
+ events["click " + this.ui.clearSearch] = 'clearSearchData';
+ events["click " + this.ui.refreshBtn] = 'onRefreshButton';
+ events["click " + this.ui.relationshipAttrFilter] = 'openAttrFilter';
+ return events;
+ },
+ /**
+ * intialize a new RelationshipSearchLayoutView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, _.pick(options, 'value', 'searchVent', 'typeHeaders', 'searchTableColumns', 'searchTableFilters', 'relationshipDefCollection', 'metricCollection', 'relationshipEventAgg'));
+ if (!this.value) {
+ this.value = {};
+ }
+ this.bindEvents();
+ },
+ bindEvents: function() {
+ this.listenTo(this.relationshipDefCollection, 'reset', function() {
+ this.renderRelationshipList();
+ this.setValues();
+ });
+ this.relationshipEventAgg.on("Relationship:Update", function(options) {
+ that.value = Utils.getUrlState.getQueryParams() || {};
+ that.initializeValues();
+ });
+ },
+ onRender: function() {
+ this.initializeValues();
+ },
+ initializeValues: function() {
+ this.renderRelationshipList();
+ this.checkForButtonVisiblity();
+ this.setValues();
+ this.renderSaveSearch();
+ },
+ renderSaveSearch: function() {
+ var that = this;
+ require(['views/search/save/SaveSearchView'], function(SaveSearchView) {
+ var saveSearchRelationshipCollection = new VSearchList(),
+ saveSearchCollection = new VSearchList();
+ saveSearchCollection.url = UrlLinks.saveSearchApiUrl();
+ saveSearchRelationshipCollection.fullCollection.comparator = function(model) {
+ return model.get('name').toLowerCase();
+ };
+ var obj = {
+ value: that.value,
+ searchVent: that.searchVent,
+ typeHeaders: that.typeHeaders,
+ fetchCollection: fetchSaveSearchCollection,
+ relationshipDefCollection: that.relationshipDefCollection,
+ getValue: function() {
+ var queryObj = that.value,
+ relationshipObj = that.searchTableFilters['relationshipFilters'],
+ urlObj = Utils.getUrlState.getQueryParams(),
+ finalObj = _.extend({}, queryObj, urlObj, {
+ 'relationshipFilters': relationshipObj ? relationshipObj[queryObj.relationshipName] : null,
+ 'relationshipName': queryObj.relationshipName,
+ 'query': queryObj.query,
+ });
+ return finalObj;
+ },
+ applyValue: function(model, searchType) {
+ that.manualRender(_.extend(searchType, CommonViewFunction.generateUrlFromSaveSearchObject({
+ value: { "searchParameters": model.get('searchParameters'), 'uiParameters': model.get('uiParameters') },
+ relationshipDefCollection: that.relationshipDefCollection
+ })));
+ }
+ }
+ that.RSaveSearchRelationship.show(new SaveSearchView(_.extend(obj, {
+ isRelationship: true,
+ collection: saveSearchRelationshipCollection.fullCollection
+ })));
+
+ function fetchSaveSearchCollection() {
+ saveSearchCollection.fetch({
+ success: function(collection, data) {
+ saveSearchRelationshipCollection.fullCollection.reset(_.where(data, { "searchType": "BASIC_RELATIONSHIP" }));
+ },
+ silent: true
+ });
+ }
+ fetchSaveSearchCollection();
+ });
+ },
+ makeFilterButtonActive: function(filtertypeParam) {
+ var filtertype = "relationshipFilters";
+ var filterObj = this.searchTableFilters['relationshipFilters'][this.value.relationshipName];
+ if (this.value.relationshipName) {
+ if (filterObj && filterObj.length) {
+ this.ui.relationshipAttrFilter.addClass('active');
+ } else {
+ this.ui.relationshipAttrFilter.removeClass('active');
+ }
+ this.ui.relationshipAttrFilter.prop('disabled', false);
+ } else {
+ this.ui.relationshipAttrFilter.removeClass('active');
+ this.ui.relationshipAttrFilter.prop('disabled', true);
+ }
+ },
+ setValues: function(paramObj) {
+ if (paramObj && paramObj.from !== "relationshipSearch") {
+ this.value = paramObj;
+ }
+ if (this.value) {
+ this.ui.relationshipLov.val(this.value.relationshipName);
+ if (this.ui.relationshipLov.data('select2')) {
+ if (this.ui.relationshipLov.val() !== this.value.relationshipName) {
+ this.value.relationshipName = null;
+ this.ui.relationshipLov.val("").trigger("change", { 'manual': true });
+ } else {
+ this.ui.relationshipLov.trigger("change", { 'manual': true });
+ }
+ }
+ }
+ },
+ renderRelationshipList: function() {
+ var relationStr = '<option></option>';
+ this.ui.relationshipLov.empty();
+ this.relationshipDefCollection.fullCollection.each(function(model) {
+ var name = Utils.getName(model.toJSON(), 'name');
+ relationStr += '<option value="' + (name) + '" data-name="' + (name) + '">' + (name) + '</option>';
+ });
+ this.ui.relationshipLov.html(relationStr);
+ var relationshipLovSelect2 = this.ui.relationshipLov.select2({
+ placeholder: "Select Relationship",
+ allowClear: true,
+ });
+ },
+ checkForButtonVisiblity: function(e, options) {
+ var isBasicSearch = true;
+ this.ui.relationshipAttrFilter.prop('disabled', true);
+ if (e && e.currentTarget) {
+ var $el = $(e.currentTarget),
+ isRelationshipEl = $el.data('id') == "relationshipLOV",
+ select2Data = $el.select2('data');
+ if (e.type === "change" && select2Data) {
+ var value = _.first($(this.ui.relationshipLov).select2('data')).id,
+ key = "relationshipName",
+ filterType = "relationshipFilters";
+ value = value && value.length ? value : null;
+ if (this.value) {
+ //On Change handle
+ if (this.value[key] !== value || (!value && !this.value[key])) {
+ var temp = {};
+ temp[key] = value;
+ _.extend(this.value, temp);
+ if (_.isUndefined(options)) {
+ this.value.pageOffset = 0;
+ }
+ } else if (isBasicSearch) {
+ // Initial loading handle.
+ if (filterType) {
+ var filterObj = this.searchTableFilters[filterType];
+ if (filterObj && this.value[key]) {
+ this.searchTableFilters[filterType][this.value[key]] = this.value[filterType] ? this.value[filterType] : null;
+ }
+ }
+ if (this.value.relationshipName) {
+ if (this.value.attributes) {
+ var attributes = _.sortBy(this.value.attributes.split(',')),
+ tableColumn = this.searchTableColumns[this.value.type];
+ if (_.isEmpty(this.searchTableColumns) || !tableColumn) {
+ this.searchTableColumns[this.value.relationshipName] = attributes
+ } else if (tableColumn.join(",") !== attributes.join(",")) {
+ this.searchTableColumns[this.value.relationshipName] = attributes;
+ }
+ } else if (this.searchTableColumns[this.value.relationshipName]) {
+ this.searchTableColumns[this.value.relationshipName] = undefined;
+ }
+ }
+ }
+ if (isBasicSearch && filterType) {
+ this.makeFilterButtonActive();
+ }
+ }
+ }
+ }
+ var value = this.ui.relationshipLov.val();
+ if (value && value.length) {
+ this.ui.searchBtn.removeAttr("disabled");
+ } else {
+ this.ui.searchBtn.attr("disabled", "true");
+ }
+ },
+ manualRender: function(paramObj) {
+ if (paramObj) {
+ this.value = paramObj;
+ }
+ this.renderRelationshipList();
+ this.setValues(paramObj);
+ },
+ okAttrFilterButton: function(e) {
+ var isTag = this.attrModal.tag ? true : false,
+ filtertype = 'relationshipFilters',
+ queryBuilderRef = this.attrModal.RQueryBuilder.currentView.ui.builder,
+ col = [];
+
+ function getIdFromRuleObject(rule) {
+ _.map(rule.rules, function(obj, key) {
+ if (_.has(obj, 'condition')) {
+ return getIdFromRuleObject(obj);
+ } else {
+ return col.push(obj.id)
+ }
+ });
+ return col;
+ }
+ if (queryBuilderRef.data('queryBuilder')) {
+ var rule = queryBuilderRef.queryBuilder('getRules');
+ }
+ if (rule) {
+ var ruleUrl = CommonViewFunction.attributeFilter.generateUrl({ "value": rule, "formatedDateToLong": true });
+ this.searchTableFilters[filtertype][(this.value.relationshipName)] = ruleUrl;
+ this.makeFilterButtonActive();
+ if (this.value && this.value.relationshipName && this.searchTableColumns) {
+ if (!this.searchTableColumns[this.value.relationshipName]) {
+ this.searchTableColumns[this.value.relationshipName] = ["name", "typeName", "end1", "end2", "label"];
+ }
+ this.searchTableColumns[this.value.relationshipName] = _.sortBy(_.union(this.searchTableColumns[this.value.relationshipName], getIdFromRuleObject(rule)));
+ }
+ this.attrModal.modal.close();
+ if ($(e.currentTarget).hasClass('search')) {
+ this.findSearchResult();
+ }
+ }
+ },
+ findSearchResult: function() {
+ this.triggerSearch(this.ui.relationshipLov.val());
+ Globals.fromRelationshipSearch = true;
+ },
+ triggerSearch: function(value) {
+ var param = {
+ relationshipName: value,
+ relationshipFilters: null,
+ searchType: 'basic'
+ };
+ if (!this.dsl) {
+ var relationFilterObj = this.searchTableFilters['relationshipFilters'];
+ if (this.value) {
+ if (this.value.relationshipName) {
+ param['relationshipFilters'] = relationFilterObj[this.value.relationshipName]
+ }
+ }
+ var columnList = this.value.relationshipName && this.searchTableColumns ? this.searchTableColumns[this.value.relationshipName] : null;
+ if (columnList) {
+ param['attributes'] = columnList.join(',');
+ }
+ }
+ _.extend(this.value, param);
+ Utils.setUrl({
+ url: '#!/relationship/relationshipSearchResult',
+ urlParams: _.extend({}, param),
+ mergeBrowserUrl: false,
+ trigger: true,
+ updateTabState: true
+ });
+ },
+ fetchCollection: function(e) {
+ this.relationshipDefCollection.fetch({ reset: true });
+ },
+ onRefreshButton: function() {
+ this.disableRefreshButton();
+ var that = this,
+ apiCount = 2,
+ updateSearchList = function() {
+ if (apiCount === 0) {
+ that.initializeValues();
+ var checkURLValue = Utils.getUrlState.getQueryParams(that.url);
+ if (that.searchVent && (_.has(checkURLValue, "relationshipName"))) {
+ that.searchVent.trigger('relationSearch:refresh');
+ }
+ }
+ };
+ this.relationshipDefCollection.fetch({
+ silent: true,
+ complete: function() {
+ --apiCount;
+ updateSearchList();
+ }
+ });
+ },
+ disableRefreshButton: function() {
+ var that = this;
+ this.ui.refreshBtn.attr('disabled', true);
+ setTimeout(function() {
+ $(that.ui.refreshBtn).attr('disabled', false);
+ }, 1000);
+ },
+ openAttrFilter: function() {
+ var that = this;
+ require(['views/search/SearchQueryView'], function(SearchQueryView) {
+ that.attrModal = new SearchQueryView({
+ value: that.value,
+ relationship: true,
+ searchVent: that.searchVent,
+ typeHeaders: that.typeHeaders,
+ entityDefCollection: that.entityDefCollection,
+ enumDefCollection: that.enumDefCollection,
+ classificationDefCollection: that.classificationDefCollection,
+ businessMetadataDefCollection: that.businessMetadataDefCollection,
+ relationshipDefCollection: that.relationshipDefCollection,
+ searchTableFilters: that.searchTableFilters,
+ });
+ that.attrModal.on('ok', function(scope, e) {
+ that.okAttrFilterButton(e);
+ });
+ });
+ },
+ clearSearchData: function() {
+ this.ui.relationshipLov.val("").trigger("change");
+ this.checkForButtonVisiblity();
+ this.searchTableFilters.relationshipFilters = {};
+ this.makeFilterButtonActive();
+ var type = "relationshipSaveSearch"
+ Utils.setUrl({
+ url: '#!/relationship',
+ urlParams: {
+ searchType: this.type
+ },
+ mergeBrowserUrl: false,
+ trigger: true
+ });
+ this.$('.' + type + ' .saveSearchList').find('li.active').removeClass('active');
+ this.$('.' + type + ' [data-id="saveBtn"]').attr('disabled', true);
+ }
+
+ });
+ return RelationshipSearchLayoutView;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/search/RelationSearchResultLayoutView.js b/dashboardv2/public/js/views/search/RelationSearchResultLayoutView.js
new file mode 100644
index 000000000..a917dd469
--- /dev/null
+++ b/dashboardv2/public/js/views/search/RelationSearchResultLayoutView.js
@@ -0,0 +1,813 @@
+/**
+ * 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',
+ 'table-dragger',
+ 'hbs!tmpl/search/RelationSearchResultLayoutView_tmpl',
+ 'modules/Modal',
+ 'models/VEntity',
+ 'utils/Utils',
+ 'utils/Globals',
+ 'collection/VRelationshipSearchResultList',
+ 'models/VCommon',
+ 'utils/CommonViewFunction',
+ 'utils/Messages',
+ 'utils/Enums',
+ 'utils/UrlLinks',
+ 'platform'
+], function(require, Backbone, tableDragger, RelationSearchResultLayoutViewTmpl, Modal, VEntity, Utils, Globals, VRelationshipSearchResultList, VCommon, CommonViewFunction, Messages, Enums, UrlLinks, platform) {
+ 'use strict';
+
+ var RelationSearchResultLayoutView = Backbone.Marionette.LayoutView.extend(
+ /** @lends RelationSearchResultLayoutView */
+ {
+ _viewName: 'RelationSearchResultLayoutView',
+
+ template: RelationSearchResultLayoutViewTmpl,
+
+ /** Layout sub regions */
+ regions: {
+ REntityTableLayoutView: "#r_relationSearchResultTableLayoutView"
+ },
+
+ /** ui selector cache */
+ ui: {
+ paginationDiv: '[data-id="paginationDiv"]',
+ previousData: "[data-id='previousData']",
+ nextData: "[data-id='nextData']",
+ pageRecordText: "[data-id='pageRecordText']",
+ colManager: "[data-id='colManager']",
+ columnEmptyInfo: "[data-id='columnEmptyInfo']",
+ showPage: "[data-id='showPage']",
+ gotoPage: "[data-id='gotoPage']",
+ gotoPagebtn: "[data-id='gotoPagebtn']",
+ activePage: "[data-id='activePage']"
+ },
+ templateHelpers: function() {
+ return {
+ searchType: this.searchType,
+ fromView: this.fromView,
+ };
+ },
+ /** ui events hash */
+ events: function() {
+ var events = {},
+ that = this;
+ events["keyup " + this.ui.gotoPage] = function(e) {
+ var code = e.which,
+ goToPage = parseInt(e.currentTarget.value);
+ if (e.currentTarget.value) {
+ that.ui.gotoPagebtn.attr('disabled', false);
+ } else {
+ that.ui.gotoPagebtn.attr('disabled', true);
+ }
+ if (code == 13) {
+ if (e.currentTarget.value) {
+ that.gotoPagebtn();
+ }
+ }
+ };
+ events["change " + this.ui.showPage] = 'changePageLimit';
+ events["click " + this.ui.gotoPagebtn] = 'gotoPagebtn';
+ events["click " + this.ui.nextData] = "onClicknextData";
+ events["click " + this.ui.previousData] = "onClickpreviousData";
+ return events;
+ },
+ /**
+ * intialize a new SearchResultLayoutView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, _.pick(options, 'value', 'guid', 'initialView', 'searchVent', 'searchTableColumns', 'isTableDropDisable', 'fromView', 'profileDBView', 'relationshipDefCollection'));
+ //this.entityModel = new VEntity();
+ this.searchCollection = new VRelationshipSearchResultList();
+ this.limit = 25;
+ this.asyncFetchCounter = 0;
+ this.offset = 0;
+ this.bindEvents();
+ this.searchType = 'Basic Search';
+ this.columnOrder = null;
+ this.defaultColumns = ["name", "typeName", "end1", "end2", "label"];
+ if (this.value) {
+ if (this.value.pageLimit) {
+ var pageLimit = parseInt(this.value.pageLimit, 10);
+ if (_.isNaN(pageLimit) || pageLimit == 0 || pageLimit <= -1) {
+ this.value.pageLimit = this.limit;
+ this.triggerUrl();
+ } else {
+ this.limit = pageLimit;
+ }
+ }
+ if (this.value.pageOffset) {
+ var pageOffset = parseInt(this.value.pageOffset, 10);
+ if (_.isNaN(pageOffset) || pageLimit <= -1) {
+ this.value.pageOffset = this.offset;
+ this.triggerUrl();
+ } else {
+ this.offset = pageOffset;
+ }
+ }
+ };
+ },
+ bindEvents: function() {
+ var that = this;
+ this.onClickLoadMore();
+ this.listenTo(this.searchCollection, "error", function(model, response) {
+ this.hideLoader({ type: 'error' });
+ var responseJSON = response && response.responseJSON ? response.responseJSON : null,
+ errorText = (responseJSON && (responseJSON.errorMessage || responseJSON.message || responseJSON.error)) || 'Invalid Expression';
+ if (errorText) {
+ Utils.notifyError({
+ content: errorText
+ });
+ this.$('.searchTable > .well').html('<center>' + _.escape(errorText) + '</center>')
+ }
+ }, this);
+ this.listenTo(this.searchCollection, "state-changed", function(state) {
+ if (Utils.getUrlState.isRelationTab()) {
+ this.updateColumnList(state);
+ var excludeDefaultColumn = [];
+ if (this.value && this.value.relationshipName) {
+ excludeDefaultColumn = _.difference(this.searchTableColumns[this.value.relationshipName], this.defaultColumns);
+ if (this.searchTableColumns[this.value.relationshipName] === null) {
+ this.ui.columnEmptyInfo.show();
+ } else {
+ this.ui.columnEmptyInfo.hide();
+ }
+ }
+ this.columnOrder = this.getColumnOrder(this.REntityTableLayoutView.$el.find('.colSort th.renderable'));
+ this.triggerUrl();
+ var attributes = this.searchCollection.filterObj.attributes;
+ if ((excludeDefaultColumn && attributes) && (excludeDefaultColumn.length > attributes.length || _.difference(excludeDefaultColumn, attributes).length)) {
+ this.fetchCollection(this.value);
+ }
+ }
+ }, this);
+ this.listenTo(this.searchVent, "relationSearch:refresh", function(model, response) {
+ this.updateColumnList();
+ this.fetchCollection();
+ }, this);
+ this.listenTo(this.searchCollection, "backgrid:sorted", function(model, response) {
+ this.checkTableFetch();
+ }, this)
+ },
+ onRender: function() {
+ this.commonTableOptions = {
+ collection: this.searchCollection,
+ includePagination: false,
+ includeFooterRecords: false,
+ includeColumnManager: (Utils.getUrlState.isRelationTab() && this.value && this.value.searchType === "basic" && !this.profileDBView ? true : false),
+ includeOrderAbleColumns: false,
+ includeSizeAbleColumns: false,
+ includeTableLoader: false,
+ includeAtlasTableSorting: true,
+ showDefaultTableSorted: true,
+ updateFullCollectionManually: true,
+ 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
+ },
+ gridOpts: {
+ emptyText: 'No Records found!',
+ className: 'table table-hover backgrid table-quickMenu colSort'
+ },
+ sortOpts: {
+ sortColumn: "name",
+ sortDirection: "ascending"
+ },
+ filterOpts: {},
+ paginatorOpts: {}
+ };
+ if (!this.initialView) {
+ var value = {
+ 'query': null,
+ 'searchType': 'basic'
+ };
+ if (this.value) {
+ value = this.value;
+ }
+ this.updateColumnList();
+ if (this.value && this.searchTableColumns && this.searchTableColumns[this.value.relationshipName] === null) {
+ this.ui.columnEmptyInfo.show();
+ } else {
+ this.ui.columnEmptyInfo.hide();
+ }
+ this.fetchCollection(value, _.extend({ 'fromUrl': true }, (this.value && this.value.pageOffset ? { 'next': true } : null)));
+ this.ui.showPage.select2({
+ data: _.sortBy(_.union([25, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500], [this.limit])),
+ tags: true,
+ dropdownCssClass: "number-input",
+ multiple: false
+ });
+ if (this.value && this.value.pageLimit) {
+ this.ui.showPage.val(this.limit).trigger('change', { "skipViewChange": true });
+ }
+ } else {
+ this.$(".relationLink").show();
+ }
+ },
+ getColumnOrderWithPosition: function() {
+ var that = this;
+ return _.map(that.columnOrder, function(value, key) {
+ return key + "::" + value;
+ }).join(",");
+ },
+ triggerUrl: function(options) {
+ Utils.setUrl(_.extend({
+ url: Utils.getUrlState.getQueryUrl().queyParams[0],
+ urlParams: this.columnOrder ? _.extend(this.value, { 'uiParameters': this.getColumnOrderWithPosition() }) : this.value,
+ mergeBrowserUrl: false,
+ trigger: false,
+ updateTabState: true
+ }, options));
+ },
+ updateColumnList: function(updatedList) {
+ if (updatedList) {
+ var listOfColumns = [];
+ _.map(updatedList, function(obj) {
+ var key = obj.name;
+ if (obj.renderable) {
+ listOfColumns.push(obj.name);
+ }
+ });
+ listOfColumns = _.sortBy(listOfColumns);
+ this.value.attributes = listOfColumns.length ? listOfColumns.join(",") : null;
+ if (this.value && this.value.relationshipName && this.searchTableColumns) {
+ this.searchTableColumns[this.value.relationshipName] = listOfColumns.length ? listOfColumns : null;
+ }
+ } else if (this.value && this.value.relationshipName && this.searchTableColumns && this.value.attributes) {
+ this.searchTableColumns[this.value.relationshipName] = this.value.attributes.split(",");
+ }
+ },
+ fetchCollection: function(value, options) {
+ var that = this,
+ isPostMethod = (this.value && this.value.searchType === "basic"),
+ isRelationSearch = Utils.getUrlState.isRelationTab(),
+ relationshipFilters = null;
+ if (isRelationSearch) {
+ relationshipFilters = CommonViewFunction.attributeFilter.generateAPIObj(this.value.relationshipFilters);
+ }
+ if (isPostMethod && isRelationSearch) {
+ var excludeDefaultColumn = this.value.relationshipName && this.searchTableColumns ? _.difference(this.searchTableColumns[this.value.relationshipName], this.defaultColumns) : null,
+ filterObj = {
+ 'attributes': excludeDefaultColumn ? excludeDefaultColumn : null,
+ 'relationshipFilters': relationshipFilters
+ };
+ }
+
+ this.showLoader();
+ if (Globals.searchApiCallRef && Globals.searchApiCallRef.readyState === 1) {
+ Globals.searchApiCallRef.abort();
+ }
+ var apiObj = {
+ skipDefaultError: true,
+ sort: false,
+ success: function(dataOrCollection, response) {
+ if (that.isDestroyed) {
+ return;
+ }
+ Globals.searchApiCallRef = undefined;
+ var isFirstPage = that.offset === 0,
+ dataLength = 0,
+ goToPage = that.ui.gotoPage.val();
+ that.ui.gotoPage.val('');
+ that.ui.gotoPage.parent().removeClass('has-error');
+ that.ui.gotoPagebtn.prop("disabled", true);
+ if (!(that.ui.pageRecordText instanceof jQuery)) {
+ return;
+ }
+ if (isPostMethod && dataOrCollection && dataOrCollection.relations) {
+ dataLength = dataOrCollection.relations.length;
+ } else {
+ dataLength = dataOrCollection.length;
+ }
+
+ if (!dataLength && that.offset >= that.limit && ((options && options.next) || goToPage) && (options && !options.fromUrl)) {
+ /* User clicks on next button and server returns
+ empty response then disabled the next button without rendering table*/
+
+ that.hideLoader();
+ var pageNumber = that.activePage + 1;
+ if (goToPage) {
+ pageNumber = goToPage;
+ that.offset = (that.activePage - 1) * that.limit;
+ } else {
+ that.finalPage = that.activePage;
+ that.ui.nextData.attr('disabled', true);
+ that.offset = that.offset - that.limit;
+ }
+ if (that.value) {
+ that.value.pageOffset = that.offset;
+ that.triggerUrl();
+ }
+ Utils.notifyInfo({
+ html: true,
+ content: Messages.search.noRecordForPage + '<b>' + Utils.getNumberSuffix({ number: pageNumber, sup: true }) + '</b> page'
+ });
+ return;
+ }
+ if (isPostMethod) {
+ that.searchCollection.reset(dataOrCollection.relations, { silent: true });
+ that.searchCollection.fullCollection.reset(dataOrCollection.relations, { silent: true });
+ }
+ /*Next button check.
+ It's outside of Previous button else condition
+ because when user comes from 2 page to 1 page than we need to check next button.*/
+ if (dataLength < that.limit) {
+ that.ui.nextData.attr('disabled', true);
+ } else {
+ that.ui.nextData.attr('disabled', false);
+ }
+
+ if (isFirstPage && (!dataLength || dataLength < that.limit)) {
+ that.ui.paginationDiv.hide();
+ } else {
+ that.ui.paginationDiv.show();
+ }
+
+ // Previous button check.
+ if (isFirstPage) {
+ that.ui.previousData.attr('disabled', true);
+ that.pageFrom = 1;
+ that.pageTo = that.limit;
+ } else {
+ that.ui.previousData.attr('disabled', false);
+ }
+
+ if (options && options.next) {
+ //on next click, adding "1" for showing the another records.
+ that.pageTo = that.offset + that.limit;
+ that.pageFrom = that.offset + 1;
+ } else if (!isFirstPage && options && options.previous) {
+ that.pageTo = that.pageTo - that.limit;
+ that.pageFrom = (that.pageTo - that.limit) + 1;
+ }
+ that.ui.pageRecordText.html("Showing <u>" + that.searchCollection.models.length + " records</u> From " + that.pageFrom + " - " + that.pageTo);
+ that.activePage = Math.round(that.pageTo / that.limit);
+ that.ui.activePage.attr('title', "Page " + that.activePage);
+ that.ui.activePage.text(that.activePage);
+ that.renderTableLayoutView();
+
+ if (dataLength > 0) {
+ that.$('.searchTable').removeClass('noData')
+ }
+
+ if (isRelationSearch && value && !that.profileDBView) {
+ var searchString = 'Results for: <span class="filterQuery">' + CommonViewFunction.generateQueryOfFilter(that.value) + "</span>";
+ that.$('.searchResult').html(searchString);
+ }
+ },
+ silent: true,
+ reset: true
+ }
+ if (value) {
+ if (value.searchType) {
+ this.searchCollection.url = UrlLinks.relationshipSearchApiUrl(value.searchType);
+ }
+ _.extend(this.searchCollection.queryParams, { 'limit': this.limit, 'offset': this.offset, 'query': _.trim(value.query), 'relationshipName': value.relationshipName || null });
+ if (isPostMethod) {
+ this.searchCollection.filterObj = _.extend({}, filterObj);
+ apiObj['data'] = _.extend(filterObj, _.pick(this.searchCollection.queryParams, 'query', 'limit', 'offset', 'relationshipName'));
+ Globals.searchApiCallRef = this.searchCollection.getBasicRearchResult(apiObj);
+ } else {
+ apiObj.data = null;
+ this.searchCollection.filterObj = null;
+ Globals.searchApiCallRef = this.searchCollection.fetch(apiObj);
+ }
+ } else {
+ _.extend(this.searchCollection.queryParams, { 'limit': this.limit, 'offset': this.offset });
+ if (isPostMethod) {
+ apiObj['data'] = _.extend(filterObj, _.pick(this.searchCollection.queryParams, 'query', 'limit', 'offset', 'relationshipName'));
+ Globals.searchApiCallRef = this.searchCollection.getBasicRearchResult(apiObj);
+ } else {
+ apiObj.data = null;
+ Globals.searchApiCallRef = this.searchCollection.fetch(apiObj);
+ }
+ }
+ },
+ tableRender: function(options) {
+ var that = this,
+ savedColumnOrder = options.order,
+ TableLayout = options.table,
+ columnCollection = Backgrid.Columns.extend({
+ sortKey: "displayOrder",
+ className: "my-awesome-css-animated-grid",
+ comparator: function(item) {
+ return item.get(this.sortKey) || 999;
+ },
+ setPositions: function() {
+ _.each(this.models, function(model, index) {
+ model.set("displayOrder", (savedColumnOrder == null ? index : parseInt(savedColumnOrder[model.get('label')])) + 1, { silent: true });
+ });
+ return this;
+ }
+ });
+ var columns = new columnCollection((that.searchCollection.dynamicTable ? that.getDaynamicColumns(that.searchCollection.toJSON()) : that.getFixedDslColumn()));
+ columns.setPositions().sort();
+ var table = new TableLayout(_.extend({}, that.commonTableOptions, {
+ columns: columns
+ }));
+ if (table.collection.length === 0) {
+ that.$(".searchTable").addClass('noData');
+ }
+ if (!that.REntityTableLayoutView) {
+ return;
+ }
+ if (!that.value) {
+ that.value = that.options.value;
+ }
+ that.REntityTableLayoutView.show(table);
+ that.$(".ellipsis-with-margin .inputAssignTag").hide();
+ table.trigger("grid:refresh"); /*Event fire when table rendered*/
+ // that.REntityTableLayoutView.$el.find('.colSort thead tr th:not(:first)').addClass('dragHandler');
+ if (that.isTableDropDisable !== true) {
+ var tableDropFunction = function(from, to, el) {
+ tableDragger(document.querySelector(".colSort")).destroy();
+ that.columnOrder = that.getColumnOrder(el.querySelectorAll('th.renderable'));
+ that.triggerUrl();
+ that.tableRender({ "order": that.columnOrder, "table": TableLayout });
+ that.checkTableFetch();
+ }
+ that.REntityTableLayoutView.$el.find('.colSort thead tr th:not(.select-all-header-cell)').addClass('dragHandler');
+ tableDragger(document.querySelector(".colSort"), { dragHandler: ".dragHandler" }).on('drop', tableDropFunction);
+ }
+ },
+ renderTableLayoutView: function(col) {
+ var that = this;
+ require(['utils/TableLayout'], function(TableLayout) {
+ // displayOrder added for column manager
+ if (that.value.uiParameters) {
+ var savedColumnOrder = _.object(that.value.uiParameters.split(',').map(function(a) {
+ return a.split('::');
+ })); // get Column position from string to object
+ }
+
+ that.tableRender({ "order": savedColumnOrder, "table": TableLayout });
+ that.checkTableFetch();
+ });
+ },
+ getColumnOrder: function(arr) {
+ var obj = {};
+ for (var i = 0; i < arr.length; ++i) {
+ var innerText = arr[i].innerText.trim();
+ obj[(innerText == "" ? 'Select' : innerText)] = i;
+ }
+ return obj;
+ },
+ checkTableFetch: function() {
+ if (this.asyncFetchCounter <= 0) {
+ this.hideLoader();
+ Utils.generatePopover({
+ el: this.$('[data-id="showMoreLess"]'),
+ contentClass: 'popover-tag-term',
+ viewFixedPopover: true,
+ popoverOptions: {
+ container: null,
+ content: function() {
+ return $(this).find('.popup-tag-term').children().clone();
+ }
+ }
+ });
+ }
+ },
+ getFixedDslColumn: function() {
+ var that = this,
+ nameCheck = 0,
+ columnToShow = null,
+ col = {};
+ this.value = this.fromView === "glossary" ? this.value : Utils.getUrlState.getQueryParams() || this.value;
+ if (this.value && this.value.searchType === "basic" && this.searchTableColumns && (this.searchTableColumns[this.value.relationshipName] !== undefined)) {
+ columnToShow = this.searchTableColumns[this.value.relationshipName] == null ? [] : this.searchTableColumns[this.value.relationshipName];
+ }
+ col['name'] = {
+ label: "Guid",
+ cell: "html",
+ editable: false,
+ resizeable: true,
+ orderable: false,
+ renderable: true,
+ className: "searchTableName",
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var obj = model.toJSON(),
+ nameHtml = "",
+ name = Utils.getName(obj),
+ img = "";
+ if (obj.guid) {
+ if (obj.guid == "-1") {
+ nameHtml = '<span title="' + name + '">' + name + '</span>';
+ } else {
+ nameHtml = '<a title="' + name + '" href="#!/relationshipDetailPage/' + obj.guid + (that.fromView ? "?from=" + that.fromView : "") + '">' + name + '</a>';
+ }
+ } else {
+ nameHtml = '<span title="' + name + '">' + name + '</span>';
+ }
+ img = "<div><img data-imgGuid='" + obj.guid + "' src='/img/entity-icon/table.png'></div>";
+ if (obj.status && Enums.entityStateReadOnly[obj.status]) {
+ nameHtml += '<button type="button" title="Deleted" class="btn btn-action btn-md deleteBtn"><i class="fa fa-trash"></i></button>';
+ nameHtml = '<div class="readOnly readOnlyLink">' + nameHtml + '</div>';
+ img = "<div><img data-imgGuid='" + obj.guid + "' src='/img/entity-icon/disabled/table.png'></div>";
+ }
+ return (img + nameHtml);
+ }
+ })
+ };
+ if (this.value) {
+ col['typeName'] = {
+ label: "Type",
+ cell: "Html",
+ editable: false,
+ resizeable: true,
+ orderable: true,
+ renderable: (columnToShow ? _.contains(columnToShow, 'typeName') : true),
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var obj = model.toJSON();
+ if (obj && obj.typeName) {
+ return '<span>' + obj.typeName + '</span>';
+ }
+ }
+ })
+ };
+ col['end1'] = {
+ label: "End1",
+ cell: "Html",
+ editable: false,
+ resizeable: true,
+ orderable: true,
+ renderable: (columnToShow ? _.contains(columnToShow, 'end1') : true),
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var obj = model.toJSON();
+ if (obj && obj.end1) {
+ var key, uniqueAttributesValue;
+ for (key in obj.end1.uniqueAttributes) {
+ uniqueAttributesValue = obj.end1.uniqueAttributes[key];
+ }
+ uniqueAttributesValue = uniqueAttributesValue ? uniqueAttributesValue : obj.end1.guid;
+ return '<a title="' + uniqueAttributesValue + '" href="#!/detailPage/' + obj.end1.guid + '?from=relationshipSearch">' + uniqueAttributesValue + '</a>';
+ }
+ }
+ })
+ };
+ col['end2'] = {
+ label: "End2",
+ cell: "Html",
+ editable: false,
+ resizeable: true,
+ orderable: true,
+ renderable: (columnToShow ? _.contains(columnToShow, 'end2') : true),
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var obj = model.toJSON();
+ if (obj && obj.end2) {
+ var key, uniqueAttributesValue;
+ for (key in obj.end2.uniqueAttributes) {
+ uniqueAttributesValue = obj.end2.uniqueAttributes[key];
+ }
+ uniqueAttributesValue = uniqueAttributesValue ? uniqueAttributesValue : obj.end2.guid;
+ return '<a title="' + uniqueAttributesValue + '" href="#!/detailPage/' + obj.end2.guid + '?from=relationshipSearch">' + uniqueAttributesValue + '</a>';
+ }
+ }
+ })
+ };
+ col['label'] = {
+ label: "Label",
+ cell: "Html",
+ editable: false,
+ resizeable: true,
+ orderable: true,
+ renderable: (columnToShow ? _.contains(columnToShow, 'end2') : true),
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var obj = model.toJSON();
+ if (obj) {
+ return "<span>" + obj.label + "</span>"
+ }
+ }
+ })
+ };
+
+ if (this.value && this.value.searchType === "basic") {
+ var def = this.relationshipDefCollection.fullCollection.find({ name: this.value.relationshipName });
+ if (def) {
+ var attrObj = def ? Utils.getNestedSuperTypeObj({ data: def.toJSON(), collection: this.relationshipDefCollection, attrMerge: true }) : [];
+ _.each(attrObj, function(obj, key) {
+ var key = obj.name,
+ isRenderable = _.contains(columnToShow, key),
+ isSortable = obj.typeName.search(/(array|map)/i) == -1;
+ col[obj.name] = {
+ label: obj.name.capitalize(),
+ cell: "Html",
+ headerCell: Backgrid.HeaderHTMLDecodeCell,
+ editable: false,
+ resizeable: true,
+ orderable: true,
+ sortable: isSortable,
+ renderable: isRenderable,
+ headerClassName: "",
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var modelObj = model.toJSON();
+ if (modelObj && modelObj.attributes && !_.isUndefined(modelObj.attributes[key])) {
+ var tempObj = {
+ 'scope': that,
+ 'attributeDefs': [obj],
+ 'valueObject': {},
+ 'isTable': false
+ };
+ tempObj.valueObject[key] = modelObj.attributes[key];
+ var tablecolumn = CommonViewFunction.propertyTable(tempObj);
+ if (_.isArray(modelObj.attributes[key])) {
+ var column = $("<div>" + tablecolumn + "</div>")
+ if (tempObj.valueObject[key].length > 2) {
+ column.addClass("toggleList semi-collapsed").append("<span><a data-id='load-more-columns'>Show More</a></span>");
+ }
+ return column;
+ }
+ return tablecolumn;
+ }
+ }
+ })
+ };
+ });
+ }
+ }
+ }
+ return this.searchCollection.constructor.getTableCols(col, this.searchCollection);
+ },
+ onClickLoadMore: function() {
+ var that = this;
+ this.$el.on('click', "[data-id='load-more-columns']", function(event) {
+ event.stopPropagation();
+ event.stopImmediatePropagation();
+ var $this = $(this),
+ $toggleList = $(this).parents('.toggleList');
+ if ($toggleList.length) {
+ if ($toggleList.hasClass('semi-collapsed')) {
+ $toggleList.removeClass('semi-collapsed');
+ $this.text("Show Less");
+ } else {
+ $toggleList.addClass('semi-collapsed');
+ $this.text("Show More");
+ }
+ }
+ });
+ },
+ getDaynamicColumns: function(valueObj) {
+ var that = this,
+ col = {};
+ if (valueObj && valueObj.length) {
+ var firstObj = _.first(valueObj);
+ _.each(_.keys(firstObj), function(key) {
+ col[key] = {
+ label: key.capitalize(),
+ cell: "Html",
+ editable: false,
+ resizeable: true,
+ orderable: true,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var modelObj = model.toJSON();
+ if (key == "name") {
+ var nameHtml = "",
+ name = _.escape(modelObj[key]);
+ if (modelObj.guid) {
+ nameHtml = '<a title="' + name + '" href="#!/detailPage/' + modelObj.guid + (that.fromView ? "?from=" + that.fromView : "") + '">' + name + '</a>';
+ } else {
+ nameHtml = '<span title="' + name + '">' + name + '</span>';
+ }
+ if (modelObj.status && Enums.entityStateReadOnly[modelObj.status]) {
+ nameHtml += '<button type="button" title="Deleted" class="btn btn-action btn-md deleteBtn"><i class="fa fa-trash"></i></button>';
+ return '<div class="readOnly readOnlyLink">' + nameHtml + '</div>';
+ }
+ return nameHtml;
+ } else if (modelObj && !_.isUndefined(modelObj[key])) {
+ var tempObj = {
+ 'scope': that,
+ // 'attributeDefs':
+ 'valueObject': {},
+ 'isTable': false
+ };
+ tempObj.valueObject[key] = modelObj[key];
+ return CommonViewFunction.propertyTable(tempObj);
+ }
+ }
+ })
+ };
+ });
+ }
+ return this.searchCollection.constructor.getTableCols(col, this.searchCollection);
+ },
+ showLoader: function() {
+ this.$('.fontLoader:not(.for-ignore)').addClass('show');
+ this.$('.tableOverlay').addClass('show');
+ },
+ hideLoader: function(options) {
+ this.$('.fontLoader:not(.for-ignore)').removeClass('show');
+ options && options.type === 'error' ? this.$('.ellipsis-with-margin,.pagination-box').hide() : this.$('.ellipsis-with-margin,.pagination-box').show(); // only show for first time and hide when type is error
+ this.$('.tableOverlay').removeClass('show');
+ },
+ onClicknextData: function() {
+ this.offset = this.offset + this.limit;
+ _.extend(this.searchCollection.queryParams, {
+ offset: this.offset
+ });
+ if (this.value) {
+ this.value.pageOffset = this.offset;
+ this.triggerUrl();
+ }
+ this.fetchCollection(null, {
+ next: true
+ });
+ },
+ onClickpreviousData: function() {
+ this.offset = this.offset - this.limit;
+ if (this.offset <= -1) {
+ this.offset = 0;
+ }
+ _.extend(this.searchCollection.queryParams, {
+ offset: this.offset
+ });
+ if (this.value) {
+ this.value.pageOffset = this.offset;
+ this.triggerUrl();
+ }
+ this.fetchCollection(null, {
+ previous: true
+ });
+ },
+ changePageLimit: function(e, obj) {
+ if (!obj || (obj && !obj.skipViewChange)) {
+ var limit = parseInt(this.ui.showPage.val());
+ if (limit == 0) {
+ this.ui.showPage.data('select2').$container.addClass('has-error');
+ return;
+ } else {
+ this.ui.showPage.data('select2').$container.removeClass('has-error');
+ }
+ this.limit = limit;
+ this.offset = 0;
+ if (this.value) {
+ this.value.pageLimit = this.limit;
+ this.value.pageOffset = this.offset;
+ this.triggerUrl();
+ }
+ _.extend(this.searchCollection.queryParams, { limit: this.limit, offset: this.offset });
+ this.fetchCollection();
+ }
+ },
+ gotoPagebtn: function(e) {
+ var that = this;
+ var goToPage = parseInt(this.ui.gotoPage.val());
+ if (!(_.isNaN(goToPage) || goToPage <= -1)) {
+ if (this.finalPage && this.finalPage < goToPage) {
+ Utils.notifyInfo({
+ html: true,
+ content: Messages.search.noRecordForPage + '<b>' + Utils.getNumberSuffix({ number: goToPage, sup: true }) + '</b> page'
+ });
+ return;
+ }
+ this.offset = (goToPage - 1) * this.limit;
+ if (this.offset <= -1) {
+ this.offset = 0;
+ }
+ _.extend(this.searchCollection.queryParams, { limit: this.limit, offset: this.offset });
+ if (this.offset == (this.pageFrom - 1)) {
+ Utils.notifyInfo({
+ content: Messages.search.onSamePage
+ });
+ } else {
+ if (this.value) {
+ this.value.pageOffset = this.offset;
+ this.triggerUrl();
+ }
+ // this.offset is updated in gotoPagebtn function so use next button calculation.
+ this.fetchCollection(null, { 'next': true });
+ }
+ }
+ }
+ });
+ return RelationSearchResultLayoutView;
+});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/search/SearchLayoutView.js b/dashboardv2/public/js/views/search/SearchLayoutView.js
index 675a521ce..020775886 100644
--- a/dashboardv2/public/js/views/search/SearchLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchLayoutView.js
@@ -38,7 +38,8 @@ define(['require',
/** Layout sub regions */
regions: {
RSaveSearchBasic: "[data-id='r_saveSearchBasic']",
- RSaveSearchAdvance: "[data-id='r_saveSearchAdvance']"
+ RSaveSearchAdvance: "[data-id='r_saveSearchAdvance']",
+ RRelationSearch: "[data-id='r_relationshipSearch']"
},
/** ui selector cache */
@@ -53,7 +54,8 @@ define(['require',
refreshBtn: '[data-id="refreshBtn"]',
advancedInfoBtn: '[data-id="advancedInfo"]',
typeAttrFilter: '[data-id="typeAttrFilter"]',
- tagAttrFilter: '[data-id="tagAttrFilter"]'
+ tagAttrFilter: '[data-id="tagAttrFilter"]',
+ tablist: '[data-id="tab-searchlist"] li'
},
/** ui events hash */
@@ -77,6 +79,20 @@ define(['require',
events["change " + this.ui.termLov] = 'checkForButtonVisiblity';
events["click " + this.ui.refreshBtn] = 'onRefreshButton';
events["click " + this.ui.advancedInfoBtn] = 'advancedInfo';
+ events["click " + this.ui.tablist] = function(e) {
+ var tabValue = $(e.currentTarget).attr('role'),
+ redirectionUrl = '#!/search';
+ this.isRelationSearch = (tabValue === "relationship-search") ? true : false;
+ if (this.isRelationSearch) {
+ redirectionUrl = '#!/relationship';
+ }
+ Utils.setUrl({
+ url: redirectionUrl,
+ mergeBrowserUrl: false,
+ trigger: true,
+ updateTabState: true
+ });
+ };
events["click " + this.ui.typeAttrFilter] = function() {
this.openAttrFilter('type');
};
@@ -137,6 +153,8 @@ define(['require',
this.tagEntityCheck = false;
this.typeEntityCheck = false;
this.bindEvents();
+ this.isRelationSearch = false;
+ this.renderRelationshipSearchView();
},
renderSaveSearch: function() {
var that = this;
@@ -207,6 +225,12 @@ define(['require',
fetchSaveSearchCollection();
});
},
+ renderRelationshipSearchView: function() {
+ var that = this;
+ require(['views/search/RelationSearchLayoutView'], function(RelationSearchLayoutView) {
+ that.RRelationSearch.show(new RelationSearchLayoutView(that.options));
+ });
+ },
bindEvents: function(param) {
var that = this;
this.listenTo(this.typeHeaders, "reset", function(value) {
@@ -367,6 +391,14 @@ define(['require',
onRender: function() {
// array of tags which is coming from url
this.initializeValues();
+ this.updateTabState();
+ },
+ updateTabState: function() {
+ if ((Utils.getUrlState.isRelationTab() || Utils.getUrlState.isRelationshipDetailPage()) && !this.isRelationSearch) {
+ var tabActive = (Utils.getUrlState.isRelationTab() || Utils.getUrlState.isRelationshipDetailPage()) ? "relationship-search" : "basic-search";
+ this.$('.nav.nav-tabs').find('[role="' + tabActive + '"]').addClass('active').siblings().removeClass('active');
+ this.$('.tab-content').find('[role="' + tabActive + '"]').addClass('active').siblings().removeClass('active');
+ }
},
updateQueryObject: function(param) {
if (param && param.searchType) {
@@ -754,6 +786,7 @@ define(['require',
},
findSearchResult: function() {
this.triggerSearch(this.ui.searchInput.val());
+ Globals.fromRelationshipSearch = false;
},
//This below function returns the searched Term Guid.
getSearchedTermGuid: function() {
diff --git a/dashboardv2/public/js/views/search/SearchQueryView.js b/dashboardv2/public/js/views/search/SearchQueryView.js
index 69a35a54b..ebe609bfc 100644
--- a/dashboardv2/public/js/views/search/SearchQueryView.js
+++ b/dashboardv2/public/js/views/search/SearchQueryView.js
@@ -52,7 +52,7 @@ define(['require',
* @constructs
*/
initialize: function(options) {
- _.extend(this, _.pick(options, 'value', 'entityDefCollection', 'typeHeaders', 'searchVent', 'enumDefCollection', 'classificationDefCollection', 'businessMetadataDefCollection', 'tag', 'searchTableFilters'));
+ _.extend(this, _.pick(options, 'value', 'entityDefCollection', 'typeHeaders', 'searchVent', 'enumDefCollection', 'classificationDefCollection', 'businessMetadataDefCollection', 'tag', 'searchTableFilters', 'relationshipDefCollection', 'relationship'));
this.bindEvents();
var that = this;
this.modal = new Modal({
@@ -106,6 +106,16 @@ define(['require',
if (Globals[this.value.tag] || Globals[Enums.addOnClassification[0]]) {
obj['systemAttrArr'] = (Globals[this.value.tag] || Globals[Enums.addOnClassification[0]]).attributeDefs;
}
+ } else if (this.relationship) {
+ obj['relationship'] = true;
+ obj['attrObj'] = this.relationshipDefCollection.fullCollection.find({ name: this.value.relationshipName });
+ if(obj.attrObj){
+ obj.attrObj = Utils.getNestedSuperTypeObj({
+ data: obj.attrObj.toJSON(),
+ collection: this.relationshipDefCollection,
+ attrMerge: true,
+ });
+ }
} else {
obj['type'] = true;
obj['attrObj'] = this.entityDefCollection.fullCollection.find({ name: this.value.type });
diff --git a/dashboardv2/public/js/views/search/save/SaveModalLayoutView.js b/dashboardv2/public/js/views/search/save/SaveModalLayoutView.js
index 350758874..3698ed649 100644
--- a/dashboardv2/public/js/views/search/save/SaveModalLayoutView.js
+++ b/dashboardv2/public/js/views/search/save/SaveModalLayoutView.js
@@ -47,7 +47,7 @@ define(['require',
},
initialize: function(options) {
var that = this;
- _.extend(this, _.pick(options, 'selectedModel', 'collection', 'getValue', 'isBasic', 'saveObj'));
+ _.extend(this, _.pick(options, 'selectedModel', 'collection', 'getValue', 'isBasic', 'saveObj', 'isRelationship'));
this.model = new VSearch();
if (this.saveObj) {
@@ -87,6 +87,8 @@ define(['require',
var saveObj = CommonViewFunction.generateObjectForSaveSearchApi(obj);
if (this.isBasic) {
saveObj['searchType'] = "BASIC";
+ } else if (this.isRelationship) {
+ saveObj['searchType'] = "BASIC_RELATIONSHIP"
} else {
saveObj['searchType'] = "ADVANCED";
}
diff --git a/dashboardv2/public/js/views/search/save/SaveSearchItemView.js b/dashboardv2/public/js/views/search/save/SaveSearchItemView.js
index a86eff4e0..0d6a10415 100644
--- a/dashboardv2/public/js/views/search/save/SaveSearchItemView.js
+++ b/dashboardv2/public/js/views/search/save/SaveSearchItemView.js
@@ -41,7 +41,7 @@ define(['require',
return events;
},
initialize: function(options) {
- _.extend(this, _.pick(options, 'collection', 'typeHeaders', 'applyValue', 'fetchFavioriteCollection', 'isBasic', 'classificationDefCollection', 'entityDefCollection', 'searchTypeObj'));
+ _.extend(this, _.pick(options, 'collection', 'typeHeaders', 'applyValue', 'fetchFavioriteCollection', 'isBasic', 'classificationDefCollection', 'entityDefCollection', 'searchTypeObj', 'isRelationship'));
this.model.id = this.model.get('guid');
this.model.idAttribute = 'guid';
},
@@ -57,13 +57,21 @@ define(['require',
'change': 'render'
},
showToolTip: function(e) {
- var that = this;
+ var that = this,
+ searchType;
+ if (that.isRelationship) {
+ searchType = "isRelationship"
+ } else if (that.isBasic) {
+ searchType = "isBasic";
+ } else {
+ searchType = "isAdvance"
+ }
Utils.generatePopover({
el: this.$('.saveSearchPopover'),
viewFixedPopover: true,
popoverOptions: {
content: function() {
- return "<ul class='saveSearchPopoverList_" + (that.isBasic ? 'isBasic' : 'isAdvance') + "' data-id=" + that.model.id + ">" +
+ return "<ul class='saveSearchPopoverList_" + searchType + "' data-id=" + that.model.id + ">" +
"<li class='listTerm' ><i class='fa fa-search'></i> <a href='javascript:void(0)' data-fn='onSearch'>Search </a></li>" +
"<li class='listTerm' ><i class='fa fa-pencil'></i> <a href='javascript:void(0)' data-fn='onRename'>Rename</a></li>" +
"<li class='listTerm' ><i class='fa fa-trash-o'></i> <a href='javascript:void(0)' data-fn='onDelete'>Delete</a></li>" +
diff --git a/dashboardv2/public/js/views/search/save/SaveSearchView.js b/dashboardv2/public/js/views/search/save/SaveSearchView.js
index 436d83db7..bc3983944 100644
--- a/dashboardv2/public/js/views/search/save/SaveSearchView.js
+++ b/dashboardv2/public/js/views/search/save/SaveSearchView.js
@@ -22,10 +22,11 @@ define(['require',
'views/search/save/SaveSearchItemView',
'collection/VSearchList',
'utils/Utils',
+ 'utils/Globals',
'utils/UrlLinks',
'utils/CommonViewFunction',
'utils/Messages'
-], function(require, Backbone, SaveSearchViewTmpl, SaveSearchItemView, VSearchList, Utils, UrlLinks, CommonViewFunction, Messages) {
+], function(require, Backbone, SaveSearchViewTmpl, SaveSearchItemView, VSearchList, Utils, Globals, UrlLinks, CommonViewFunction, Messages) {
'use strict';
return Backbone.Marionette.CompositeView.extend({
@@ -42,8 +43,10 @@ define(['require',
typeHeaders: this.typeHeaders,
applyValue: this.applyValue,
isBasic: this.isBasic,
+ isRelationship: this.isRelationship,
classificationDefCollection: this.classificationDefCollection,
entityDefCollection: this.entityDefCollection,
+ relationshipDefCollection: this.relationshipDefCollection,
fetchFavioriteCollection: this.fetchCollection.bind(this),
searchTypeObj: this.searchTypeObj
};
@@ -63,7 +66,7 @@ define(['require',
},
initialize: function(options) {
var that = this;
- _.extend(this, _.pick(options, 'collection', 'value', 'searchVent', 'typeHeaders', 'applyValue', 'getValue', 'isBasic', 'fetchCollection', 'classificationDefCollection', 'entityDefCollection'));
+ _.extend(this, _.pick(options, 'collection', 'value', 'searchVent', 'typeHeaders', 'applyValue', 'getValue', 'isBasic', 'isRelationship', 'fetchCollection', 'classificationDefCollection', 'entityDefCollection', 'relationshipDefCollection'));
this.searchTypeObj = {
'searchType': 'dsl',
'dslChecked': 'true'
@@ -77,7 +80,15 @@ define(['require',
this.bindEvents();
},
bindEvents: function() {
- var that = this;
+ var that = this,
+ searchType;
+ if (that.isRelationship) {
+ searchType = "isRelationship"
+ } else if (that.isBasic) {
+ searchType = "isBasic";
+ } else {
+ searchType = "isAdvance"
+ }
this.listenTo(this.collection, "add reset error remove", function(model, collection) {
this.$('.fontLoader-relative').hide();
if (this.collection && this.collection.length) {
@@ -86,7 +97,7 @@ define(['require',
this.$(".noFavoriteSearch").show();
}
}, this);
- $('body').on('click', '.saveSearchPopoverList_' + (this.isBasic ? 'isBasic' : 'isAdvance') + ' li', function(e) {
+ $('body').on('click', '.saveSearchPopoverList_' + searchType + ' li', function(e) {
that.$('.saveSearchPopover').popover('hide');
var id = $(this).parent('ul').data('id');
that[$(this).find('a').data('fn')]({
@@ -102,6 +113,12 @@ define(['require',
'getValue': this.getValue,
'isBasic': this.isBasic
});
+ } else if (value && value.relationshipName) {
+ this.callSaveModalLayoutView({
+ 'collection': this.collection,
+ 'getValue': this.getValue,
+ 'isRelationship': this.isRelationship
+ });
} else {
Utils.notifyInfo({
content: Messages.search.favoriteSearch.notSelectedSearchFilter
@@ -115,12 +132,22 @@ define(['require',
modal: true,
html: true,
ok: function(argument) {
- that.callSaveModalLayoutView({
- 'saveObj': obj,
- 'collection': that.collection,
- 'getValue': that.getValue,
- 'isBasic': that.isBasic
- })
+ if (that.isRelationship) {
+ that.callSaveModalLayoutView({
+ 'saveObj': obj,
+ 'collection': that.collection,
+ 'getValue': that.getValue,
+ 'isRelationship': that.isRelationship,
+ });
+ } else {
+ that.callSaveModalLayoutView({
+ 'saveObj': obj,
+ 'collection': that.collection,
+ 'getValue': that.getValue,
+ 'isBasic': that.isBasic,
+ });
+ }
+
},
cancel: function(argument) {}
},
@@ -146,18 +173,32 @@ define(['require',
onSearch: function(options) {
if (options && options.model) {
var searchParameters = options.model.toJSON().searchParameters,
+ searchType = options.model.get('searchType'),
params = CommonViewFunction.generateUrlFromSaveSearchObject({
value: { "searchParameters": searchParameters, "uiParameters": options.model.get('uiParameters') },
classificationDefCollection: this.classificationDefCollection,
- entityDefCollection: this.entityDefCollection
+ entityDefCollection: this.entityDefCollection,
+ relationshipDefCollection: this.relationshipDefCollection
});
- Utils.setUrl({
- url: '#!/search/searchResult',
- urlParams: _.extend({}, this.searchTypeObj, params),
- mergeBrowserUrl: false,
- trigger: true,
- updateTabState: true
- });
+ if (searchType === "BASIC_RELATIONSHIP") {
+ Globals.fromRelationshipSearch = true;
+ Utils.setUrl({
+ url: '#!/relationship/relationshipSearchResult',
+ urlParams: _.extend({}, { 'searchType': 'basic' }, params),
+ mergeBrowserUrl: false,
+ trigger: true,
+ updateTabState: true
+ });
+ } else {
+ Globals.fromRelationshipSearch = false;
+ Utils.setUrl({
+ url: '#!/search/searchResult',
+ urlParams: _.extend({}, this.searchTypeObj, params),
+ mergeBrowserUrl: false,
+ trigger: true,
+ updateTabState: true
+ });
+ }
}
},
onRename: function(options) {
@@ -166,7 +207,7 @@ define(['require',
require([
'views/search/save/SaveModalLayoutView'
], function(SaveModalLayoutView) {
- new SaveModalLayoutView({ 'selectedModel': options.model, 'collection': that.collection, 'getValue': that.getValue, 'isBasic': that.isBasic });
+ new SaveModalLayoutView({ 'selectedModel': options.model, 'collection': that.collection, 'getValue': that.getValue, 'isBasic': that.isBasic, 'isRelationship': that.isRelationship });
});
}
},
diff --git a/dashboardv2/public/js/views/site/Header.js b/dashboardv2/public/js/views/site/Header.js
index ffb582ed4..ecca92952 100644
--- a/dashboardv2/public/js/views/site/Header.js
+++ b/dashboardv2/public/js/views/site/Header.js
@@ -110,7 +110,7 @@ define(['require',
},
setSearchBoxWidth: function(options) {
var atlasHeaderWidth = this.$el.find(".atlas-header").width(),
- minusWidth = (Utils.getUrlState.isDetailPage() || Utils.getUrlState.isBSDetail()) ? 360 : 210;
+ minusWidth = (Utils.getUrlState.isDetailPage() || Utils.getUrlState.isRelationshipDetailPage() || Utils.getUrlState.isBSDetail()) ? 360 : 210;
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 e0f717a24..4aa41b40a 100644
--- a/dashboardv2/public/js/views/site/SideNavLayoutView.js
+++ b/dashboardv2/public/js/views/site/SideNavLayoutView.js
@@ -116,7 +116,7 @@ define(['require',
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() || Utils.getUrlState.isAdministratorTab() || Utils.getUrlState.isDebugMetricsTab()) {
+ if (Utils.getUrlState.isSearchTab() || Utils.getUrlState.isRelationTab() || Utils.getUrlState.isRelationshipDetailPage() || Utils.getUrlState.isInitial() || Utils.getUrlState.isAdministratorTab() || Utils.getUrlState.isDebugMetricsTab()) {
activeTab({ "view": "search" });
} else if (Utils.getUrlState.isTagTab()) {
activeTab({ "view": "classification" });
diff --git a/dashboardv3/public/css/scss/common.scss b/dashboardv3/public/css/scss/common.scss
index 036d2cfcc..c0f65fdab 100644
--- a/dashboardv3/public/css/scss/common.scss
+++ b/dashboardv3/public/css/scss/common.scss
@@ -94,6 +94,10 @@
font-weight: bold;
}
}
+
+ .relationship-detailpage-panel {
+ width: 58% !important;
+ }
}
pre {
diff --git a/dashboardv3/public/css/scss/leftsidebar.scss b/dashboardv3/public/css/scss/leftsidebar.scss
index 68a6f79a1..ebe24f248 100644
--- a/dashboardv3/public/css/scss/leftsidebar.scss
+++ b/dashboardv3/public/css/scss/leftsidebar.scss
@@ -308,6 +308,10 @@
.basic-tree:after {
content: "B";
}
+
+ .relationship-tree:after {
+ content: "R"
+ }
}
.switch-button {
diff --git a/dashboardv3/public/js/collection/VRelationshipSearchList.js b/dashboardv3/public/js/collection/VRelationshipSearchList.js
new file mode 100644
index 000000000..16d8b845d
--- /dev/null
+++ b/dashboardv3/public/js/collection/VRelationshipSearchList.js
@@ -0,0 +1,58 @@
+/**
+ * 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',
+ 'collection/BaseCollection',
+ 'models/VRelationshipSearch',
+ 'utils/UrlLinks'
+], function(require, BaseCollection, VRelationshipSearch, UrlLinks) {
+ 'use strict';
+ var VRelationshipSearchList = BaseCollection.extend(
+ //Prototypal attributes
+ {
+ url: UrlLinks.baseURL,
+
+ model: VRelationshipSearch,
+
+ initialize: function() {
+ this.modelName = 'VRelationshipSearch';
+ this.modelAttrName = 'results';
+ },
+ getRelationship: function(id, options) {
+ var url = UrlLinks.relationshipApiUrl(id);
+
+ options = _.extend({
+ contentType: 'application/json',
+ dataType: 'json'
+ }, options);
+
+ return this.constructor.nonCrudOperation.call(this, url, 'GET', options);
+ }
+ },
+ //Static Class Members
+ {
+ /**
+ * Table Cols to be passed to Backgrid
+ * UI has to use this as base and extend this.
+ *
+ */
+ tableCols: {}
+ }
+ );
+ return VRelationshipSearchList;
+});
\ No newline at end of file
diff --git a/dashboardv3/public/js/collection/VRelationshipSearchResultList.js b/dashboardv3/public/js/collection/VRelationshipSearchResultList.js
new file mode 100644
index 000000000..3befb8593
--- /dev/null
+++ b/dashboardv3/public/js/collection/VRelationshipSearchResultList.js
@@ -0,0 +1,87 @@
+/**
+ * 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',
+ 'collection/BaseCollection',
+ 'models/VRelationSearch',
+ 'utils/UrlLinks'
+], function(require, BaseCollection, VRelationSearch, UrlLinks) {
+ 'use strict';
+ var VRelationshipSearchResultList = BaseCollection.extend(
+ //Prototypal attributes
+ {
+ url: UrlLinks.relationshipSearchApiUrl(),
+
+ model: VRelationSearch,
+
+ initialize: function(options) {
+ _.extend(this, options);
+ this.modelName = 'VRelationshipSearchResultList';
+ this.modelAttrName = '';
+ this.dynamicTable = false;
+ },
+ parseRecords: function(resp, options) {
+ this.queryType = resp.queryType;
+ this.queryText = resp.queryText;
+ this.referredEntities = resp.referredEntities;
+ if (resp.attributes) {
+ this.dynamicTable = true;
+ var entities = [];
+ _.each(resp.attributes.values, function(obj) {
+ var temp = {};
+ _.each(obj, function(val, index) {
+ var key = resp.attributes.name[index];
+ if (key == "__guid") {
+ key = "guid"
+ }
+ temp[key] = val;
+ });
+ entities.push(temp);
+ });
+ return entities;
+ } else if (resp.entities) {
+ this.dynamicTable = false;
+ return resp.entities ? resp.entities : [];
+ } else {
+ return [];
+ }
+ },
+ getBasicRearchResult: function(options) {
+ var url = UrlLinks.relationshipSearchApiUrl('basic');
+
+ options = _.extend({
+ contentType: 'application/json',
+ dataType: 'json',
+ }, options);
+ options.data = JSON.stringify(options.data);
+
+ return this.constructor.nonCrudOperation.call(this, url, 'POST', options);
+ }
+ },
+ //Static Class Members
+ {
+ /**
+ * Table Cols to be passed to Backgrid
+ * UI has to use this as base and extend this.
+ *
+ */
+ tableCols: {}
+ }
+ );
+ return VRelationshipSearchResultList;
+});
\ No newline at end of file
diff --git a/dashboardv3/public/js/main.js b/dashboardv3/public/js/main.js
index b1aaec26b..9fdd73ea3 100644
--- a/dashboardv3/public/js/main.js
+++ b/dashboardv3/public/js/main.js
@@ -237,13 +237,14 @@ require(['App',
'utils/UrlLinks',
'collection/VEntityList',
'collection/VTagList',
+ 'collection/VRelationshipSearchList',
'utils/Enums',
'utils/Utils',
'utils/Overrides',
'bootstrap',
'd3',
'select2'
-], function(App, Router, Helper, CommonViewFunction, Globals, UrlLinks, VEntityList, VTagList, Enums, Utils) {
+], function(App, Router, Helper, CommonViewFunction, Globals, UrlLinks, VEntityList, VTagList, VRelationshipSearchList, Enums, Utils) {
var that = this;
this.asyncFetchCounter = 5 + (Enums.addOnEntities.length + 1);
// entity
@@ -267,6 +268,10 @@ require(['App',
this.businessMetadataDefCollection = new VEntityList();
this.businessMetadataDefCollection.url = UrlLinks.businessMetadataDefApiUrl();
this.businessMetadataDefCollection.modelAttrName = "businessMetadataDefs";
+ //relationship
+ this.relationshipDefCollection = new VRelationshipSearchList();
+ this.relationshipDefCollection.url = UrlLinks.relationshipDefApiUrl();
+ this.relationshipDefCollection.modelAttrName = "relationshipDefs";
App.appRouter = new Router({
entityDefCollection: this.entityDefCollection,
@@ -275,7 +280,8 @@ require(['App',
classificationDefCollection: this.classificationDefCollection,
metricCollection: this.metricCollection,
classificationAndMetricEvent: this.classificationAndMetricEvent,
- businessMetadataDefCollection: this.businessMetadataDefCollection
+ businessMetadataDefCollection: this.businessMetadataDefCollection,
+ relationshipDefCollection: this.relationshipDefCollection
});
var startApp = function() {
@@ -418,6 +424,16 @@ require(['App',
startApp();
}
});
+ this.relationshipDefCollection.fetch({
+ async:true,
+ complete: function() {
+ that.relationshipDefCollection.fullCollection.comparator = function(model) {
+ return model.get('name').toLowerCase();
+ };
+ that.relationshipDefCollection.fullCollection.sort({ silent: true });
+ startApp();
+ }
+ });
CommonViewFunction.fetchRootEntityAttributes({
url: UrlLinks.rootEntityDefUrl(Enums.addOnEntities[0]),
entity: Enums.addOnEntities,
diff --git a/dashboardv3/public/js/models/VRelationSearch.js b/dashboardv3/public/js/models/VRelationSearch.js
new file mode 100644
index 000000000..6ce5b879f
--- /dev/null
+++ b/dashboardv3/public/js/models/VRelationSearch.js
@@ -0,0 +1,54 @@
+/**
+ * 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',
+ 'models/BaseModel',
+ 'utils/UrlLinks'
+], function(require, VBaseModel, UrlLinks) {
+ 'use strict';
+ var VRelationSearch = VBaseModel.extend({
+ urlRoot: UrlLinks.relationshipSearchApiUrl(),
+
+ defaults: {},
+
+ serverSchema: {},
+
+ idAttribute: 'id',
+
+ initialize: function() {
+ this.modelName = 'VRelationSearch';
+ },
+ toString: function() {
+ return this.get('name');
+ },
+ /*************************
+ * Non - CRUD operations
+ *************************/
+ getEntity: function(id, options) {
+ var url = UrlLinks.relationApiUrl({ guid: id });
+
+ options = _.extend({
+ contentType: 'application/json',
+ dataType: 'json'
+ }, options);
+
+ return this.constructor.nonCrudOperation.call(this, url, 'GET', options);
+ }
+ }, {});
+ return VRelationSearch;
+});
\ No newline at end of file
diff --git a/dashboardv3/public/js/models/VRelationshipSearch.js b/dashboardv3/public/js/models/VRelationshipSearch.js
new file mode 100644
index 000000000..f981091ee
--- /dev/null
+++ b/dashboardv3/public/js/models/VRelationshipSearch.js
@@ -0,0 +1,55 @@
+/**
+ * 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',
+ 'models/BaseModel',
+ 'utils/UrlLinks'
+], function(require, VBaseModel, UrlLinks) {
+ 'use strict';
+ var VRelationshipSearch = VBaseModel.extend({
+
+ urlRoot: UrlLinks.relationshipSearchApiUrl(),
+
+ defaults: {},
+
+ serverSchema: {},
+
+ idAttribute: 'id',
+
+ initialize: function() {
+ this.modelName = 'VRelationshipSearch';
+ },
+ toString: function() {
+ return this.get('name');
+ },
+ /*************************
+ * Non - CRUD operations
+ *************************/
+
+ getRelationship: function(id, options) {
+ var url = UrlLinks.relationshipSearchApiUrl({ guid: id});
+ options = _.extend({
+ contentType: 'application/json',
+ dataType: 'json'
+ }, options);
+
+ return this.constructor.nonCrudOperation.call(this, url, 'GET', options);
+ }
+ }, {});
+ return VRelationshipSearch;
+});
\ No newline at end of file
diff --git a/dashboardv3/public/js/router/Router.js b/dashboardv3/public/js/router/Router.js
index 8e8cf1557..a48b4cc78 100644
--- a/dashboardv3/public/js/router/Router.js
+++ b/dashboardv3/public/js/router/Router.js
@@ -36,6 +36,10 @@ define([
"!/search/searchResult": function() {
this.renderDefaultSearchLayoutView({ fromSearchResultView: true });
},
+ //Relationship
+ "!/relationship/relationshipSearchResult": function() {
+ this.renderDefaultSearchLayoutView({ fromSearchResultView: true, isRelationshipSearch: true });
+ },
// Tag
"!/tag": "renderTagLayoutView",
"!/tag/tagAttribute/(*name)": "renderTagLayoutView",
@@ -44,6 +48,8 @@ define([
"!/glossary/:id": "renderGlossaryLayoutView",
// Details
"!/detailPage/:id": "detailPage",
+ //Relationship Detail Page
+ "!/relationshipDetailPage/:id": "relationshipDetailPage",
//Audit table
'!/administrator': 'administrator',
'!/administrator/businessMetadata/:id': 'businessMetadataDetailPage',
@@ -55,7 +61,7 @@ define([
initialize: function(options) {
_.extend(
this,
- _.pick(options, "entityDefCollection", "typeHeaders", "enumDefCollection", "classificationDefCollection", "metricCollection", "classificationAndMetricEvent", "businessMetadataDefCollection")
+ _.pick(options, "entityDefCollection", "typeHeaders", "enumDefCollection", "classificationDefCollection", "metricCollection", "classificationAndMetricEvent", "businessMetadataDefCollection", "relationshipDefCollection")
);
this.showRegions();
this.bindCommonEvents();
@@ -75,7 +81,8 @@ define([
glossaryCollection: this.glossaryCollection,
metricCollection: this.metricCollection,
classificationAndMetricEvent: this.classificationAndMetricEvent,
- businessMetadataDefCollection: this.businessMetadataDefCollection
+ businessMetadataDefCollection: this.businessMetadataDefCollection,
+ relationshipDefCollection: this.relationshipDefCollection
};
this.ventObj = {
searchVent: this.searchVent,
@@ -88,7 +95,8 @@ define([
},
searchTableFilters: {
tagFilters: {},
- entityFilters: {}
+ entityFilters: {},
+ relationshipFilters: {}
}
};
},
@@ -208,6 +216,37 @@ define([
});
}
},
+ relationshipDetailPage: function(id) {
+ var that = this;
+ if (id) {
+ require(["views/site/Header", "views/detail_page/RelationshipDetailPageLayoutView", "views/site/SideNavLayoutView"], function(Header, RelationshipDetailPageLayoutView, SideNavLayoutView) {
+ var paramObj = Utils.getUrlState.getQueryParams(),
+ options = _.extend({}, that.preFetchedCollectionLists, that.sharedObj, that.ventObj);
+ that.renderViewIfNotExists(that.getHeaderOptions(Header));
+ that.renderViewIfNotExists({
+ view: App.rSideNav,
+ manualRender: function() {
+ this.view.currentView.manualRender(options);
+ },
+ render: function() {
+ return new SideNavLayoutView(options);
+ }
+ });
+
+ var dOptions = _.extend({ id: id, value: paramObj }, options);
+ that.renderViewIfNotExists({
+ view: App.rContent,
+ viewName: "RelationshipDetailPageLayoutView",
+ manualRender: function() {
+ this.view.currentView.manualRender(dOptions);
+ },
+ render: function() {
+ return new RelationshipDetailPageLayoutView(dOptions);
+ }
+ });
+ });
+ }
+ },
renderTagLayoutView: function(tagName) {
var that = this;
require(["views/site/Header", "views/tag/TagContainerLayoutView", "views/site/SideNavLayoutView"], function(Header, TagContainerLayoutView, SideNavLayoutView) {
@@ -296,7 +335,16 @@ define([
require(["views/site/Header", "views/search/SearchDefaultLayoutView", "views/site/SideNavLayoutView", "collection/VTagList"], function(Header, SearchDefaultLayoutView, SideNavLayoutView, VTagList) {
var paramObj = Utils.getUrlState.getQueryParams();
tag = new VTagList();
- if (paramObj && (paramObj.type || paramObj.tag || paramObj.term || paramObj.query || paramObj.udKeys || paramObj.udLabels) === undefined) {
+ if (opt && opt.isRelationshipSearch) {
+ paramObj = _.pick(paramObj, ["relationshipName", "searchType", "isCF", "relationshipFilters", "attributes", "uiParameters", "pageLimit", "pageOffset"]);
+ } else {
+ if (paramObj && paramObj.relationshipName) {
+ paramObj = _.omit(paramObj, ["relationshipName", "relationshipFilters", "attributes"]);
+ } else {
+ paramObj = _.omit(paramObj, ["relationshipName"]);
+ }
+ }
+ if (paramObj && (paramObj.type || paramObj.tag || paramObj.term || paramObj.query || paramObj.udKeys || paramObj.udLabels || paramObj.relationshipName) === undefined) {
Utils.setUrl({
url: "#!/search",
mergeBrowserUrl: false,
@@ -304,7 +352,7 @@ define([
updateTabState: true
});
}
- if (Utils.getUrlState.getQueryUrl().lastValue !== "search" && Utils.getUrlState.isAdministratorTab() === false) {
+ if (Utils.getUrlState.getQueryUrl().lastValue !== "search" && Utils.getUrlState.isAdministratorTab() === false && Utils.getUrlState.isRelationTab() === false) {
paramObj = _.omit(paramObj, ["tabActive", "ns", "nsa"]);
Utils.setUrl({
url: "#!/search/searchResult",
@@ -314,12 +362,27 @@ define([
updateTabState: true
});
}
+ if (Utils.getUrlState.getQueryUrl().lastValue !== "relationship" && Utils.getUrlState.isRelationTab() === true) {
+ Utils.setUrl({
+ url: "#!/relationship/relationshipSearchResult",
+ urlParams: paramObj,
+ mergeBrowserUrl: false,
+ trigger: false,
+ updateTabState: true
+ });
+ }
+
if (paramObj) {
if (!paramObj.type) {
if (paramObj.entityFilters) {
paramObj.entityFilters = null;
}
}
+ if (!paramObj.relationshipName) {
+ if (paramObj.relationshipFilters) {
+ paramObj.relationshipFilters = null;
+ }
+ }
if (!paramObj.tag) {
if (paramObj.tagFilters) {
paramObj.tagFilters = null;
@@ -376,7 +439,7 @@ define([
isinitialView =
(
paramObj.type ||
- (paramObj.dslChecked == "true" ? "" : paramObj.tag || paramObj.term) ||
+ (paramObj.dslChecked == "true" ? "" : paramObj.tag || paramObj.term || paramObj.relationshipName) ||
(paramObj.query ? paramObj.query.trim() : "")
).length === 0;
}
diff --git a/dashboardv3/public/js/templates/detail_page/RelationshipDetailPageLayoutView_tmpl.html b/dashboardv3/public/js/templates/detail_page/RelationshipDetailPageLayoutView_tmpl.html
new file mode 100644
index 000000000..46df153cb
--- /dev/null
+++ b/dashboardv3/public/js/templates/detail_page/RelationshipDetailPageLayoutView_tmpl.html
@@ -0,0 +1,125 @@
+<!--
+ * 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="back-button" title="Back to search page">
+ <i class="fa fa-angle-left" data-id="backButton"></i>
+ </div>
+ <div class="fontLoader">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ <div class="relationshipDetail form-horizontal col-sm-12">
+ <h1 class="title">
+ <div data-id="entityIcon" class="entity-icon-box position-relative"></div>
+ <span data-id="title"></span>
+ </h1>
+ </div>
+ <div class="row">
+ <div class="col-sm-12 default-tab">
+ <ul class="nav nav-tabs" data-id="tab-list">
+ <li role="properties" class="tab active"><a href="#tab-details" aria-controls="tab-details" role="tab" data-toggle="tab">Properties</a></li>
+ </ul>
+ </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_otherProperties">
+ <div class="panel-group" id="accordion">
+ <div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="entity">
+ <div class="panel-heading relationship-detailpage-panel" data-toggle="collapse" href="#collapse4" aria-expanded="true">
+ <h4 class="panel-title">
+ <a>Technical properties </a>
+ </h4>
+ <div class="btn-group pull-left">
+ <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
+ </div>
+ </div>
+ <div id="collapse4" class="panel-collapse collapse in">
+ <div class="panel-body">
+ <div class="entity-detail-table">
+ <table class="table bold-key">
+ <tbody data-id="otherAttributes" class="hide-empty-value">
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="col-md-6 loader-row">
+ <div id="r_relationshipDetailTableLayoutView">
+ <div class="fontLoader-relative">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ </div>
+ <div id="r_end1View">
+ <div class="panel-group" id="accordion">
+ <div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="entity">
+ <div class="panel-heading relationship-detailpage-panel" data-toggle="collapse" href="#collapse2" aria-expanded="false">
+ <h4 class="panel-title">
+ <a>End 1 </a>
+ </h4>
+ <div class="btn-group pull-left">
+ <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
+ </div>
+ </div>
+ <div id="collapse2" class="panel-collapse collapse">
+ <div class="panel-body">
+ <div class="entity-detail-table">
+ <table class="table bold-key">
+ <tbody data-id="relationshipEnd1" class="hide-empty-value">
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div id="r_end2View">
+ <div class="panel-group" id="accordion">
+ <div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="entity">
+ <div class="panel-heading relationship-detailpage-panel" data-toggle="collapse" href="#collapse3" aria-expanded="false">
+ <h4 class="panel-title">
+ <a>End 2 </a>
+ </h4>
+ <div class="btn-group pull-left">
+ <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
+ </div>
+ </div>
+ <div id="collapse3" class="panel-collapse collapse">
+ <div class="panel-body">
+ <div class="entity-detail-table">
+ <table class="table bold-key">
+ <tbody data-id="relationshipEnd2" class="hide-empty-value">
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+</div>
\ No newline at end of file
diff --git a/dashboardv3/public/js/templates/entity/EntityDetailTableLayoutView_tmpl.html b/dashboardv3/public/js/templates/entity/EntityDetailTableLayoutView_tmpl.html
index 3fe0e95e5..d83d2d717 100644
--- a/dashboardv3/public/js/templates/entity/EntityDetailTableLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/entity/EntityDetailTableLayoutView_tmpl.html
@@ -18,7 +18,11 @@
<div class="panel panel-default custom-panel expand_collapse_panel-icon" data-id="entity">
<div class="panel-heading" data-toggle="collapse" href="#collapse1" aria-expanded="true" style="width: 58%">
<h4 class="panel-title">
+ {{#ifCond isRelationshipDetailPage "!==" true}}
<a>Technical properties </a>
+ {{else}}
+ <a>Relationship properties </a>
+ {{/ifCond}}
</h4>
<div class="btn-group pull-left">
<button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
@@ -27,9 +31,11 @@
<div class="panel-actions">
<div class="pretty p-switch p-fill" style="margin-right: 20px">
<input type="checkbox" data-id="noValueToggle" title="Show empty values" />
+ {{#ifCond isRelationshipDetailPage "!==" true}}
<div class="state p-primary">
<label></label>
</div>
+ {{/ifCond}}
</div>
{{#ifCond editEntity "===" true}}
<button data-id="editButton" title="Edit Entity" class="btn btn-action btn-sm pull-right">Edit</button>
diff --git a/dashboardv3/public/js/templates/search/RelationSearchResultLayoutView_tmpl.html b/dashboardv3/public/js/templates/search/RelationSearchResultLayoutView_tmpl.html
new file mode 100644
index 000000000..5fc9e55ff
--- /dev/null
+++ b/dashboardv3/public/js/templates/search/RelationSearchResultLayoutView_tmpl.html
@@ -0,0 +1,103 @@
+<!--
+ * 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="position-relative">
+ <div class="tableOverlay"></div>
+ <!-- Not for table Loader its only for initial loading -->
+ <div class="fontLoader" style="z-index:999">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ <!-- <div class="col-sm-12 attributeResultContainer form-group">
+ <button title="Refresh Search Result" class="btn btn-action btn-sm" data-id="refreshRelationSearchResult" data-original-title="Refresh Search Result"><i class="fa fa-refresh"></i></button>
+ <button class="btn-action btn-sm attribute-filter-text" data-id='relationAttrFilter'> <i class="fa fa-angle-right"></i> Filters</button>
+ <button class='btn-action btn-sm' data-id='clearRelationSearch'>Clear</button>
+ </div> -->
+ <div class="ellipsis-with-margin" style="display: none;"><span class="searchResult" style=" font-size: 16px;"></span></div>
+ <div class="searchTable">
+ <div class="no-data" style="display: none;">
+ <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 class="pagination-box clearfix row" style="display: none;{{#unless isSearchTab}}margin-top: 0px;{{/unless}}">
+ <div class="form-group filter-box col-md-12" {{#if isSearchTab}} style="position: absolute;right: 0;top: -44px; padding: 0;width:auto" {{/if}}>
+ <div class="pull-right inline-content-fr no-padding-left">
+ {{#if isSearchTab}}
+ <div class="inline" data-id="colManager"></div>
+ {{/if}}
+ </div>
+ </div>
+ </div>
+ <div id="r_relationSearchResultTableLayoutView" class="col-sm-12">
+ </div>
+ <div class="pagination-box searach-result-pagination col-sm-12 no-padding" 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">
+ <i class="fa fa-angle-left" aria-hidden="true"></i>
+ </button>
+ </li>
+ <li class="active">
+ <a href="javascript:void(0)" data-id="activePage"></a>
+ </li>
+ <li>
+ <button type="button" data-id="nextData" title="Next">
+ <i class="fa fa-angle-right" aria-hidden="true"></i>
+ </button>
+ </li>
+ </ul>
+ </div>
+ <div class="inline col-sm-4" data-id="paginationDiv">
+ <div class="input-group" data-id="goToPageDiv">
+ <input type="text" class="form-control number-input" data-id="gotoPage" placeholder="Goto Page" />
+ <span class="input-group-btn">
+ <button class="btn btn-default" type="button" data-id="gotoPagebtn" title="Goto Page" disabled="disabled">
+ Go!
+ </button>
+ </span>
+ </div>
+ </div>
+ <div class="inline">
+ <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>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+</div>
+<div class="text-center" data-id="columnEmptyInfo" style="display: none;">
+ <h4>Please select one/more column to see the data</h4>
+</div>
\ No newline at end of file
diff --git a/dashboardv3/public/js/templates/search/SearchDefaultLayoutView_tmpl.html b/dashboardv3/public/js/templates/search/SearchDefaultLayoutView_tmpl.html
index 7a5a322c7..a82bdb94e 100644
--- a/dashboardv3/public/js/templates/search/SearchDefaultLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/search/SearchDefaultLayoutView_tmpl.html
@@ -104,6 +104,23 @@
</div>
</div>
</div>
+ <div class="panel panel-default expand_collapse_panel-icon" data-id="relationshipRegion">
+ <div class="panel-heading" data-toggle="collapse" href="#collapseRelationship" aria-expanded="true">
+ <h4 class="panel-title">
+ <a>Relationship: <span class="relationshipName"></span></a>
+ </h4>
+ <div class="btn-group pull-right">
+ <button type="button" title="Collapse"><i class="ec-icon fa"></i></button>
+ </div>
+ </div>
+ <div id="collapseRelationship" class="panel-collapse collapse in">
+ <div class="panel-body">
+ <div id='r_attributeQueryBuilderRelationship' 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>
diff --git a/dashboardv3/public/js/templates/search/SearchFilterBrowseLayoutView_tmpl.html b/dashboardv3/public/js/templates/search/SearchFilterBrowseLayoutView_tmpl.html
index 9ca345539..ef9afddff 100644
--- a/dashboardv3/public/js/templates/search/SearchFilterBrowseLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/search/SearchFilterBrowseLayoutView_tmpl.html
@@ -44,6 +44,9 @@
<div class="col-sm-12">
<div data-id="r_glossaryTreeRender"></div>
</div>
+ <div class="col-sm-12">
+ <div data-id="r_relationshipTreeRender"></div>
+ </div>
<div class="col-sm-12">
<div data-id="r_customFilterTreeRender"></div>
</div>
diff --git a/dashboardv3/public/js/templates/search/SearchResultLayoutView_tmpl.html b/dashboardv3/public/js/templates/search/SearchResultLayoutView_tmpl.html
index b16a4d28a..876f5c26e 100644
--- a/dashboardv3/public/js/templates/search/SearchResultLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/search/SearchResultLayoutView_tmpl.html
@@ -38,8 +38,8 @@
<div class="pagination-box clearfix row" style="display: none;{{#unless isSearchTab}}margin-top: 0px;{{/unless}}">
<div class="form-group filter-box col-md-12" {{#if isSearchTab}} style="position: absolute;right: 0;top: -44px; padding: 0;width:auto" {{/if}}>
<div class="pull-right inline-content-fr no-padding-left">
- {{#if isSearchTab}}
<div class="inline" data-id="colManager"></div>
+ {{#if isSearchTab}}
{{#if entityCreate}}
<div class="inline"><button class="btn btn-action btn-sm" data-id="createEntity"><i class="fa fa-plus"></i> Create Entity</button></div>
{{/if}}
diff --git a/dashboardv3/public/js/templates/search/tree/RelationshipLayoutView_tmpl.html b/dashboardv3/public/js/templates/search/tree/RelationshipLayoutView_tmpl.html
new file mode 100644
index 000000000..423d7d3e9
--- /dev/null
+++ b/dashboardv3/public/js/templates/search/tree/RelationshipLayoutView_tmpl.html
@@ -0,0 +1,33 @@
+<!--
+ * 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 expand_collapse_panel-icon right-icons">
+ <div class="panel-heading dash-button-icon clearfix" data-toggle="collapse" aria-expanded="true" href="#c_relationships">
+ <i class="ec-icon fa"></i>
+ <h4 class="panel-title">Relationships</h4>
+ <div class="btn-group pull-right">
+ <button type="button" class="typeRefresh" data-id="refreshTree" data-type="relationship" title="Refresh">
+ <i class="fa fa-refresh"></i>
+ </button>
+ </div>
+ </div>
+ <div id="c_relationships" class="panel-collapse collapse jstree-with-action in">
+ <div class="relationshipsTree" data-id="relationshipSearchTree"></div>
+ <div class="text-center" data-id="relationshipTreeLoader">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/dashboardv3/public/js/utils/CommonViewFunction.js b/dashboardv3/public/js/utils/CommonViewFunction.js
index 7d8f03d2e..5b2b0c2dc 100644
--- a/dashboardv3/public/js/utils/CommonViewFunction.js
+++ b/dashboardv3/public/js/utils/CommonViewFunction.js
@@ -87,6 +87,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
showListCount = options.showListCount || true,
highlightString = options.highlightString,
formatStringVal = options.formatStringVal,
+ isRelationshipAttr = options.isRelationshipAttribute, //For relationshipDetailpage
numberFormat = options.numberFormat || _.numberFormatWithComma;
var table = "",
@@ -197,7 +198,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
valueOfArray.push('<span class="json-string">' + tmpVal + '</span>');
}
}
- } else if (_.isObject(inputOutputField) && !id) {
+ } else if ((_.isObject(inputOutputField) && (!id || isRelationshipAttr))) {
var attributesList = inputOutputField;
if (scope.typeHeaders && inputOutputField.typeName) {
var typeNameCategory = scope.typeHeaders.fullCollection.findWhere({ name: inputOutputField.typeName });
@@ -228,7 +229,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
valueOfArray.push(Utils.JSONPrettyPrint(attributesList, getValue));
}
}
- if (id && inputOutputField) {
+ if (id && inputOutputField && !isRelationshipAttr) {
var name = Utils.getName(inputOutputField);
if ((name === "-" || name === id) && !inputOutputField.attributes) {
var fetch = true;
@@ -305,10 +306,17 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
if (options.guidHyperLink === false) {
val = getValue(keyValue, key);
} else {
- val = '<a title="' + key + '" href="#!/detailPage/' + _.escape(keyValue) + '">' + getValue(keyValue, key) + '</a>';
+ if (isRelationshipAttr) {
+ val = '<a title="' + key + '" href="#!/detailPage/' + _.escape(keyValue) + '?from=relationshipSearch">' + getValue(keyValue, key) + '</a>';
+ } else {
+ val = '<a title="' + key + '" href="#!/detailPage/' + _.escape(keyValue) + '">' + getValue(keyValue, key) + '</a>';
+ }
}
} else {
val = getValue(keyValue, key);
+ if (isRelationshipAttr && (key === "createTime" || key === "updateTime")) {
+ val = Utils.formatDate({ date: keyValue });
+ }
}
if (isTable) {
var value = val,
@@ -414,6 +422,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
value = Utils.getUrlState.getQueryParams();
var entityFilters = CommonViewFunction.attributeFilter.extractUrl({ "value": value.entityFilters, "formatDate": true }),
tagFilters = CommonViewFunction.attributeFilter.extractUrl({ "value": value.tagFilters, "formatDate": true }),
+ relationshipFilters = CommonViewFunction.attributeFilter.extractUrl({ "value": value.relationshipFilters, "formatDate": true }),
queryArray = [];
function objToString(filterObj, type) {
@@ -453,6 +462,14 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
}
queryArray.push('<div class="group">' + tagKeyValue + '</div>');
}
+ if (value.relationshipName) {
+ var relationshipKeyValue = isCapsuleView ? '<div class="capsuleView"><span class="key">Relationship:</span><span class="value">' + _.escape(value.relationshipName) + '</span><div class="fa fa-close clear-attr" data-type="relationshipName"></div></div>' : '<span class="key">Relationship:</span><span class="value">' + _.escape(value.relationshipName) + '</span>';
+ if (relationshipFilters) {
+ var conditionForRealtionship = (relationshipFilters.rules && relationshipFilters.rules.length == 1) ? '' : 'AND';
+ relationshipKeyValue += '<span class="operator">' + conditionForRealtionship + '</span><div class="sub-group"><span>(</span><span class="operator">' + relationshipFilters.condition + '</span><span>(</span>' + objToString(relationshipFilters, "relationshipFilters").join("") + '<span>)</span><span>)</span></div>';
+ }
+ queryArray.push('<div class="group">' + relationshipKeyValue + '</div>');
+ }
if (value.term) {
var termKeyValue = isCapsuleView ? '<div class="capsuleView"><span class="key">Term:</span><span class="value">' + _.escape(value.term) + '</span><div class="fa fa-close clear-attr" data-type="term"></div></div>' : '<span class="key">Term:</span><span class="value">' + _.escape(value.term) + '</span>';
queryArray.push('<div class="group">' + termKeyValue + '</div>');
@@ -498,7 +515,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
if (!_.isUndefinedNull(val)) {
if (k == "attributes") {
val = val.split(',');
- } else if (_.contains(["tagFilters", "entityFilters"], k)) {
+ } else if (_.contains(["tagFilters", "entityFilters", "relationshipFilters"], k)) {
val = CommonViewFunction.attributeFilter.generateAPIObj(val);
} else if (_.contains(["includeDE", "excludeST", "excludeSC"], k)) {
val = val ? false : true;
@@ -523,6 +540,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
var value = options.value,
classificationDefCollection = options.classificationDefCollection,
entityDefCollection = options.entityDefCollection,
+ relationshipDefCollection = options.relationshipDefCollection,
obj = {};
if (value) {
_.each(Enums.extractFromUrlForSearch, function(svalue, skey) {
@@ -570,6 +588,22 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
}
}
val = CommonViewFunction.attributeFilter.generateUrl({ "value": val, "attributeDefs": attributeDefs });
+ } else if (k == "relationshipFilters") {
+ if (relationshipDefCollection) {
+ var relationshipDef = relationshipDefCollection.fullCollection.findWhere({ 'name': value[skey].relationshipName }),
+ attributeDefs = [];
+ if (relationshipDef) {
+ attributeDefs = Utils.getNestedSuperTypeObj({
+ collection: relationshipDefCollection,
+ attrMerge: true,
+ data: relationshipDef.toJSON()
+ });
+ }
+ if (Globals[value[skey].relationshipName]) {
+ attributeDefs = Globals[value[skey].relationshipName].attributeDefs;
+ }
+ }
+ val = CommonViewFunction.attributeFilter.generateUrl({ "value": val, "attributeDefs": attributeDefs });
} else if (_.contains(["includeDE", "excludeST", "excludeSC"], k)) {
val = val ? false : true;
}
diff --git a/dashboardv3/public/js/utils/Enums.js b/dashboardv3/public/js/utils/Enums.js
index ee80313c2..00bbe103d 100644
--- a/dashboardv3/public/js/utils/Enums.js
+++ b/dashboardv3/public/js/utils/Enums.js
@@ -103,6 +103,7 @@ define(["require", "backbone"], function(require) {
"searchParameters": {
"pageLimit": "limit",
"type": "typeName",
+ "relationshipName": "relationshipName",
"tag": "classification",
"query": "query",
"pageOffset": "offset",
@@ -111,6 +112,7 @@ define(["require", "backbone"], function(require) {
"excludeSC": "includeSubClassifications",
"tagFilters": "tagFilters",
"entityFilters": "entityFilters",
+ "relationshipFilters": "relationshipFilters",
"attributes": "attributes",
"term": "termName"
},
diff --git a/dashboardv3/public/js/utils/Globals.js b/dashboardv3/public/js/utils/Globals.js
index 9a51c4dc4..6b4dafb78 100644
--- a/dashboardv3/public/js/utils/Globals.js
+++ b/dashboardv3/public/js/utils/Globals.js
@@ -33,7 +33,8 @@ define(["require", "underscore"], function(require, _) {
searchUrl: "#!/search",
glossaryUrl: "#!/glossary",
administratorUrl: "#!/administrator",
- debugMetricsUrl: "#!/debugMetrics"
+ debugMetricsUrl: "#!/debugMetrics",
+ relationUrl: '#!/relationSearch'
},
detailPageState: {}
};
@@ -58,6 +59,7 @@ define(["require", "underscore"], function(require, _) {
Globals.isLineageOnDemandEnabled = false;
Globals.lineageNodeCount = 3;
Globals.lineageDepth = 3;
+ Globals.fromRelationshipSearch = false;
return Globals;
});
\ No newline at end of file
diff --git a/dashboardv3/public/js/utils/UrlLinks.js b/dashboardv3/public/js/utils/UrlLinks.js
index b9a9c8174..2531f1e74 100644
--- a/dashboardv3/public/js/utils/UrlLinks.js
+++ b/dashboardv3/public/js/utils/UrlLinks.js
@@ -43,6 +43,9 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
enumDefApiUrl: function(name) {
return this.getDefApiUrl('enum', name);
},
+ relationshipDefApiUrl: function() {
+ return this.getDefApiUrl('relationship', name);
+ },
metricsApiUrl: function() {
return this.baseUrl + '/admin/metrics'
},
@@ -109,6 +112,16 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
return entitiesUrl += '?minExtInfo=' + (minExtInfo);
}
},
+ relationApiUrl: function(options) {
+ var relationsUrl = this.baseUrlV2 + '/relationship';
+ if (options) {
+ var guid = options.guid,
+ name = options.name;
+ if (guid)
+ relationsUrl += '/guid/' + guid;
+ }
+ return relationsUrl;
+ },
entityLabelsAPIUrl: function(guid) {
return this.entitiesApiUrl({ guid: guid }) + "/labels";
},
@@ -173,6 +186,9 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
return relationshipUrl
}
},
+ relationshipSearchApiUrl: function() {
+ return this.baseUrlV2 + '/search/relations';
+ },
schemaApiUrl: function(guid) {
var lineageUrl = this.baseUrl + '/lineage';
if (guid) {
diff --git a/dashboardv3/public/js/utils/Utils.js b/dashboardv3/public/js/utils/Utils.js
index 0d8722fa9..40e5f0cfd 100644
--- a/dashboardv3/public/js/utils/Utils.js
+++ b/dashboardv3/public/js/utils/Utils.js
@@ -355,6 +355,8 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
urlUpdate['administratorUrl'] = options.url;
} else if (Utils.getUrlState.isDebugMetricsTab(options.url)) {
urlUpdate['debugMetricsUrl'] = options.url;
+ } else if (Utils.getUrlState.isRelationTab(options.url)) {
+ urlUpdate['relationUrl'] = options.url;
}
$.extend(Globals.saveApplicationState.tabState, urlUpdate);
}
@@ -396,6 +398,18 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
matchString: "search"
});
},
+ isRelationTab: function(url) {
+ return this.checkTabUrl({
+ url: url,
+ matchString: "relationship"
+ });
+ },
+ isRelationSearch: function(url) {
+ return this.checkTabUrl({
+ url: url,
+ matchString: "relationship/relationshipSearchResult"
+ });
+ },
isAdministratorTab: function(url) {
return this.checkTabUrl({
url: url,
@@ -424,6 +438,12 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
matchString: "detailPage"
});
},
+ isRelationshipDetailPage: function(url) {
+ return this.checkTabUrl({
+ url: url,
+ matchString: "relationshipDetailPage"
+ });
+ },
getLastValue: function() {
return this.getQueryUrl().lastValue;
},
@@ -584,6 +604,9 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
urlPath = "administratorUrl";
}
}
+ if (Globals.fromRelationshipSearch) {
+ urlPath = 'relationUrl';
+ }
Utils.setUrl({
url: Globals.saveApplicationState.tabState[urlPath],
mergeBrowserUrl: false,
diff --git a/dashboardv3/public/js/views/detail_page/DetailPageLayoutView.js b/dashboardv3/public/js/views/detail_page/DetailPageLayoutView.js
index 471be3bd7..a64032278 100644
--- a/dashboardv3/public/js/views/detail_page/DetailPageLayoutView.js
+++ b/dashboardv3/public/js/views/detail_page/DetailPageLayoutView.js
@@ -444,7 +444,7 @@ define(['require',
this.updateTab();
},
onDestroy: function() {
- if (!Utils.getUrlState.isDetailPage()) {
+ if (!Utils.getUrlState.isDetailPage() && !Utils.getUrlState.isRelationshipDetailPage()) {
$('body').removeClass("detail-page");
}
},
diff --git a/dashboardv3/public/js/views/detail_page/RelationshipDetailPageLayoutView.js b/dashboardv3/public/js/views/detail_page/RelationshipDetailPageLayoutView.js
new file mode 100644
index 000000000..4f5377a3b
--- /dev/null
+++ b/dashboardv3/public/js/views/detail_page/RelationshipDetailPageLayoutView.js
@@ -0,0 +1,212 @@
+/**
+ * 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/detail_page/RelationshipDetailPageLayoutView_tmpl',
+ 'utils/Utils',
+ 'utils/CommonViewFunction',
+ 'utils/Globals',
+ 'utils/Enums',
+ 'utils/Messages',
+ 'utils/UrlLinks',
+ 'collection/VEntityList'
+], function(require, Backbone, RelationshipDetailPageLayoutView, Utils, CommonViewFunction, Globals, Enums, Messages, UrlLinks, VEntityList) {
+ 'use strict';
+
+ var RelationshipDetailPageLayoutView = Backbone.Marionette.LayoutView.extend(
+ /** @lends DetailPageLayoutView */
+ {
+ _viewName: 'RelationshipDetailPageLayoutView',
+
+ template: RelationshipDetailPageLayoutView,
+
+ /** Layout sub regions */
+ regions: {
+ RRelationshipDetailTableLayoutView: "#r_relationshipDetailTableLayoutView"
+ },
+ /** ui selector cache */
+ ui: {
+ title: '[data-id="title"]',
+ entityIcon: '[data-id="entityIcon"]',
+ relationshipEnd1: '[data-id="relationshipEnd1"]',
+ relationshipEnd2: '[data-id="relationshipEnd2"]',
+ otherAttributes: '[data-id="otherAttributes"]',
+ backButton: '[data-id="backButton"]'
+ },
+ templateHelpers: function() {
+ },
+ /** ui events hash */
+ events: function() {
+ var events = {};
+ events["click " + this.ui.backButton] = function() {
+ Utils.backButtonClick();
+ }
+ return events;
+ },
+ /**
+ * intialize a new DetailPageLayoutView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, _.pick(options, 'value', 'collection', 'id', 'relationshipDefCollection', 'searchVent'));
+ $('body').addClass("detail-page");
+ this.collection = new VEntityList([], {});
+ this.collection.url = UrlLinks.relationApiUrl({ guid: this.id, minExtInfo: true });
+ this.fetchCollection();
+ },
+ bindEvents: function() {
+ var that = this;
+ this.listenTo(this.collection, 'reset', function() {
+ this.relationshipObject = this.collection.first().toJSON();
+ var collectionJSON = this.relationshipObject.relationship,
+ name = collectionJSON ? Utils.getName(collectionJSON) : "";
+ if (collectionJSON) {
+ this.readOnly = Enums.entityStateReadOnly[collectionJSON.status];
+ if (name && collectionJSON.typeName) {
+ name = name + ' (' + _.escape(collectionJSON.typeName) + ')';
+ }
+ if (this.readOnly) {
+ this.$el.addClass('readOnly');
+ } else {
+ this.$el.removeClass('readOnly');
+ }
+ if (name) {
+ this.ui.title.show();
+ var titleName = '<span>' + name + '</span>';
+ if (this.readOnly) {
+ titleName += '<button title="Deleted" class="btn btn-action btn-md deleteBtn"><i class="fa fa-trash"></i> Deleted</button>';
+ }
+ if (this.readOnly) {
+ this.ui.entityIcon.addClass('disabled');
+ } else {
+ this.ui.entityIcon.removeClass('disabled');
+ }
+ this.ui.title.html(titleName);
+ var entityData = _.extend({}, collectionJSON),
+ img = this.readOnly ? '<img src="/img/entity-icon/disabled/table.png"/>' : '<img src="/img/entity-icon/table.png"/>';
+ this.ui.entityIcon.attr('title', _.escape(collectionJSON.typeName)).html(img);
+ } else {
+ this.ui.title.hide();
+ }
+ }
+ this.hideLoader();
+ var obj = {
+ entity: collectionJSON,
+ guid: this.id,
+ entityName: name,
+ fetchCollection: this.fetchCollection.bind(that),
+ searchVent: this.searchVent,
+ attributeDefs: (function() {
+ return that.getEntityDef(collectionJSON);
+ })(),
+ isRelationshipDetailPage: true
+ }
+ this.renderRelationshipDetailTableLayoutView(obj);
+ this.ui.relationshipEnd1.empty().html(this.renderRelationAttributesDetails({
+ scope: this,
+ valueObject: collectionJSON.end1,
+ isRelationshipAttribute: true,
+ guidHyperLink: true
+ }));
+ this.ui.relationshipEnd2.empty().html(this.renderRelationAttributesDetails({
+ scope: this,
+ valueObject: collectionJSON.end2,
+ isRelationshipAttribute: true,
+ guidHyperLink: true
+ }));
+ this.ui.otherAttributes.empty().html(this.renderRelationAttributesDetails({
+ scope: this,
+ valueObject: _.pick(collectionJSON, 'createTime', 'createdBy', 'blockedPropagatedClassifications', 'guid', 'label', 'propagateTags', 'propagatedClassifications', 'provenanceType', 'status', 'updateTime', 'updatedBy', 'version'),
+ isRelationshipAttribute: true,
+ guidHyperLink: false
+ }));
+ }, this);
+ this.listenTo(this.collection, 'error', function(model, response) {
+ this.$('.fontLoader-relative').removeClass('show');
+ if (response.responseJSON) {
+ Utils.notifyError({
+ content: response.responseJSON.errorMessage || response.responseJSON.error
+ });
+ }
+ }, this);
+ },
+ onRender: function() {
+ var that = this;
+ this.bindEvents();
+ Utils.showTitleLoader(this.$('.page-title .fontLoader'), this.$('.relationshipDetail'));
+ this.$('.fontLoader-relative').addClass('show'); // to show tab loader
+ },
+ manualRender: function(options) {
+ if (options) {
+ var oldId = this.id;
+ _.extend(this, _.pick(options, 'value', 'id'));
+ if (this.id !== oldId) {
+ this.collection.url = UrlLinks.relationApiUrl({ guid: this.id, minExtInfo: true });
+ this.fetchCollection();
+ }
+ }
+ },
+ onDestroy: function() {
+ if (!Utils.getUrlState.isRelationshipDetailPage() && !Utils.getUrlState.isDetailPage()) {
+ $('body').removeClass("detail-page");
+ }
+ },
+ fetchCollection: function() {
+ this.collection.fetch({ reset: true });
+ if (this.searchVent) {
+ this.searchVent.trigger('relationshipList:refresh');
+ }
+ },
+ getEntityDef: function(entityObj) {
+ if (this.activeEntityDef) {
+ var data = this.activeEntityDef.toJSON();
+ var attributeDefs = Utils.getNestedSuperTypeObj({
+ data: data,
+ attrMerge: true,
+ collection: this.relationshipDefCollection
+ });
+ return attributeDefs;
+ } else {
+ return [];
+ }
+ },
+ hideLoader: function() {
+ Utils.hideTitleLoader(this.$('.page-title .fontLoader'), this.$('.relationshipDetail'));
+ },
+ showLoader: function() {
+ Utils.showTitleLoader(this.$('.page-title .fontLoader'), this.$('.relationshipDetail'));
+ },
+ renderRelationshipDetailTableLayoutView: function(obj) {
+ var that = this;
+ require(['views/entity/EntityDetailTableLayoutView'], function(EntityDetailTableLayoutView) {
+ that.RRelationshipDetailTableLayoutView.show(new EntityDetailTableLayoutView(obj));
+ });
+ },
+ renderRelationAttributesDetails: function(options) {
+ var table = CommonViewFunction.propertyTable({
+ scope: options.scope,
+ valueObject: options.valueObject,
+ isRelationshipAttribute: options.isRelationshipAttribute,
+ guidHyperLink: options.guidHyperLink
+ });
+ return table;
+ }
+ });
+ return RelationshipDetailPageLayoutView;
+});
\ No newline at end of file
diff --git a/dashboardv3/public/js/views/entity/EntityDetailTableLayoutView.js b/dashboardv3/public/js/views/entity/EntityDetailTableLayoutView.js
index 5eee4d711..eb4647c2c 100644
--- a/dashboardv3/public/js/views/entity/EntityDetailTableLayoutView.js
+++ b/dashboardv3/public/js/views/entity/EntityDetailTableLayoutView.js
@@ -34,7 +34,8 @@ define(['require',
templateHelpers: function() {
return {
- editEntity: this.editEntity
+ editEntity: this.editEntity,
+ isRelationshipDetailPage: this.isRelationshipDetailPage
};
},
@@ -66,7 +67,7 @@ define(['require',
* @constructs
*/
initialize: function(options) {
- _.extend(this, _.pick(options, 'entity', 'typeHeaders', 'attributeDefs', 'attributes', 'editEntity', 'guid', 'entityDefCollection', 'searchVent', 'fetchCollection'));
+ _.extend(this, _.pick(options, 'entity', 'typeHeaders', 'attributeDefs', 'attributes', 'editEntity', 'guid', 'entityDefCollection', 'searchVent', 'fetchCollection', 'isRelationshipDetailPage'));
this.entityModel = new VEntity({});
this.showAllProperties = false;
},
diff --git a/dashboardv3/public/js/views/search/QueryBuilderView.js b/dashboardv3/public/js/views/search/QueryBuilderView.js
index 3b4a95317..f2cd0c774 100644
--- a/dashboardv3/public/js/views/search/QueryBuilderView.js
+++ b/dashboardv3/public/js/views/search/QueryBuilderView.js
@@ -56,9 +56,12 @@ define(['require',
* @constructs
*/
initialize: function(options) {
- _.extend(this, _.pick(options, 'attrObj', 'value', 'typeHeaders', 'entityDefCollection', 'enumDefCollection', 'classificationDefCollection', 'businessMetadataDefCollection', 'tag', 'type', 'searchTableFilters', 'systemAttrArr', 'adminAttrFilters'));
+ _.extend(this, _.pick(options, 'attrObj', 'value', 'typeHeaders', 'entityDefCollection', 'enumDefCollection', 'classificationDefCollection', 'businessMetadataDefCollection', 'tag', 'type', 'searchTableFilters', 'systemAttrArr', 'adminAttrFilters', 'relationship'));
this.attrObj = _.sortBy(this.attrObj, 'name');
this.filterType = this.tag ? 'tagFilters' : 'entityFilters';
+ if(this.relationship){
+ this.filterType = 'relationshipFilters';
+ }
this.defaultRange = "Last 7 Days";
this.dateRangesMap = {
'Today': [moment(), moment()],
@@ -403,10 +406,13 @@ define(['require',
rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters ? this.searchTableFilters["adminAttrFilters"] : null, "formatDate": true });;
} else {
if (this.value) {
- rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters[this.filterType][(this.tag ? this.value.tag : this.value.type)], "formatDate": true });
+ rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters[this.filterType][(this.tag ? this.value.tag : this.value.type) || this.value.relationshipName], "formatDate": true });
}
_.each(this.attrObj, function(obj) {
var type = that.tag ? that.value.tag : that.value.type;
+ if (that.value.relationshipName) {
+ type = that.value.relationshipName;
+ }
var returnObj = that.getObjDef(obj, rules_widgets, isGroupView, (type + ' Attribute'));
if (returnObj) {
filters.push(returnObj);
diff --git a/dashboardv3/public/js/views/search/RelationSearchResultLayoutView.js b/dashboardv3/public/js/views/search/RelationSearchResultLayoutView.js
new file mode 100644
index 000000000..a8a64ab79
--- /dev/null
+++ b/dashboardv3/public/js/views/search/RelationSearchResultLayoutView.js
@@ -0,0 +1,804 @@
+/**
+ * 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',
+ 'table-dragger',
+ 'hbs!tmpl/search/SearchResultLayoutView_tmpl',
+ 'modules/Modal',
+ 'models/VEntity',
+ 'utils/Utils',
+ 'utils/Globals',
+ 'collection/VRelationshipSearchResultList',
+ 'models/VCommon',
+ 'utils/CommonViewFunction',
+ 'utils/Messages',
+ 'utils/Enums',
+ 'utils/UrlLinks',
+ 'moment',
+ 'platform'
+], function(require, Backbone, tableDragger, SearchResultLayoutViewTmpl, Modal, VEntity, Utils, Globals, VRelationshipSearchResultList, VCommon, CommonViewFunction, Messages, Enums, UrlLinks, moment, platform) {
+ 'use strict';
+ var RelationSearchResultLayoutView = Backbone.Marionette.LayoutView.extend(
+ /** @lends RelationSearchResultLayoutView */
+ {
+ _viewName: 'SearchResultLayoutView',
+
+ template: SearchResultLayoutViewTmpl,
+
+ /** Layout sub regions */
+ regions: {
+ REntityTableLayoutView: "#r_searchResultTableLayoutView",
+ RSearchQuery: '#r_searchQuery'
+ },
+
+ /** ui selector cache */
+ ui: {
+ paginationDiv: '[data-id="paginationDiv"]',
+ previousData: "[data-id='previousData']",
+ nextData: "[data-id='nextData']",
+ pageRecordText: "[data-id='pageRecordText']",
+ colManager: "[data-id='colManager']",
+ columnEmptyInfo: "[data-id='columnEmptyInfo']",
+ showPage: "[data-id='showPage']",
+ gotoPage: "[data-id='gotoPage']",
+ gotoPagebtn: "[data-id='gotoPagebtn']",
+ activePage: "[data-id='activePage']",
+ saveFilter: "[data-id='saveFilter']"
+ },
+ templateHelpers: function() {
+ return {
+ searchType: this.searchType,
+ fromView: this.fromView,
+ isSearchTab: Utils.getUrlState.isRelationSearch()
+ };
+ },
+ /** ui events hash */
+ events: function() {
+ var events = {},
+ that = this;
+ events["keyup " + this.ui.gotoPage] = function(e) {
+ var code = e.which,
+ goToPage = parseInt(e.currentTarget.value);
+ if (e.currentTarget.value) {
+ that.ui.gotoPagebtn.attr('disabled', false);
+ } else {
+ that.ui.gotoPagebtn.attr('disabled', true);
+ }
+ if (code == 13) {
+ if (e.currentTarget.value) {
+ that.gotoPagebtn();
+ }
+ }
+ };
+ events["change " + this.ui.showPage] = 'changePageLimit';
+ events["click " + this.ui.gotoPagebtn] = 'gotoPagebtn';
+ events["click " + this.ui.nextData] = "onClicknextData";
+ events["click " + this.ui.previousData] = "onClickpreviousData";
+ events["click " + this.ui.saveFilter] = function() {
+ if (this.searchVent) {
+ this.searchVent.trigger("SaveRelationship:Filter");
+ }
+ };
+ return events;
+ },
+ /**
+ * intialize a new SearchResultLayoutView Layout
+ * @constructs
+ */
+ initialize: function(options) {
+ _.extend(this, _.pick(options, 'value', 'guid', 'initialView', 'searchVent', 'searchTableColumns', 'isTableDropDisable', 'fromView', 'relationshipDefCollection'));
+ this.entityModel = new VEntity();
+ this.searchCollection = new VRelationshipSearchResultList();
+ this.limit = 25;
+ this.asyncFetchCounter = 0;
+ this.offset = 0;
+ this.bindEvents();
+ this.searchType = 'Basic Search';
+ this.columnOrder = null;
+ this.defaultColumns = ["name", "typeName", "end1", "end2", "label"];
+ if (this.value) {
+ if (this.value.pageLimit) {
+ var pageLimit = parseInt(this.value.pageLimit, 10);
+ if (_.isNaN(pageLimit) || pageLimit == 0 || pageLimit <= -1) {
+ this.value.pageLimit = this.limit;
+ this.triggerUrl();
+ } else {
+ this.limit = pageLimit;
+ }
+ }
+ if (this.value.pageOffset) {
+ var pageOffset = parseInt(this.value.pageOffset, 10);
+ if (_.isNaN(pageOffset) || pageLimit <= -1) {
+ this.value.pageOffset = this.offset;
+ this.triggerUrl();
+ } else {
+ this.offset = pageOffset;
+ }
+ }
+ };
+ if (platform.name === "IE") {
+ this.isTableDropDisable = true;
+ }
+ },
+ bindEvents: function() {
+ var that = this;
+ this.listenTo(this.searchCollection, "error", function(model, response) {
+ this.hideLoader({ type: 'error' });
+ var responseJSON = response && response.responseJSON ? response.responseJSON : null,
+ errorText = (responseJSON && (responseJSON.errorMessage || responseJSON.message || responseJSON.error || responseJSON.msgDesc)) || 'Something went wrong';
+ if (errorText) {
+ Utils.notifyError({
+ content: errorText
+ });
+ this.$('.searchTable > .well').html('<center>' + errorText + '</center>')
+ }
+ }, this);
+ this.listenTo(this.searchCollection, "state-changed", function(state) {
+ if (Utils.getUrlState.isRelationTab()) {
+ this.updateColumnList(state);
+ var excludeDefaultColumn = [];
+ if (this.value && this.value.relationshipName) {
+ excludeDefaultColumn = _.difference(this.searchTableColumns[this.value.relationshipName], this.defaultColumns);
+ if (this.searchTableColumns[this.value.relationshipName] === null) {
+ this.ui.columnEmptyInfo.show();
+ } else {
+ this.ui.columnEmptyInfo.hide();
+ }
+ }
+ this.columnOrder = this.getColumnOrder(this.REntityTableLayoutView.$el.find('.colSort th.renderable'));
+ this.triggerUrl();
+ var attributes = this.searchCollection.filterObj.attributes;
+ if ((excludeDefaultColumn && attributes) && (excludeDefaultColumn.length > attributes.length || _.difference(excludeDefaultColumn, attributes).length)) {
+ this.fetchCollection(this.value);
+ }
+ }
+ }, this);
+ this.listenTo(this.searchVent, "relationSearch:refresh", function(model, response) {
+ this.fetchCollection();
+ }, this);
+ this.listenTo(this.searchCollection, "backgrid:sorted", function(model, response) {
+ this.checkTableFetch();
+ }, this);
+ },
+ onRender: function() {
+ if (Utils.getUrlState.isSearchTab()) {
+ this.$(".action-box").hide();
+ }
+ this.commonTableOptions = {
+ collection: this.searchCollection,
+ includePagination: false,
+ includeFooterRecords: false,
+ includeColumnManager: (Utils.getUrlState.isRelationTab() && this.value && this.value.searchType === "basic" ? true : false),
+ includeOrderAbleColumns: false,
+ includeSizeAbleColumns: false,
+ includeTableLoader: false,
+ includeAtlasTableSorting: true,
+ showDefaultTableSorted: true,
+ updateFullCollectionManually: true,
+ 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
+ },
+ gridOpts: {
+ emptyText: 'No Records found!',
+ className: 'table table-hover backgrid table-quickMenu colSort'
+ },
+ sortOpts: {
+ sortColumn: "name",
+ sortDirection: "ascending"
+ },
+ filterOpts: {},
+ paginatorOpts: {}
+ };
+ if (!this.initialView) {
+ var value = {
+ 'query': null,
+ 'searchType': 'basic'
+ };
+ if (this.value) {
+ value = this.value;
+ }
+ this.updateColumnList();
+ if (this.value && this.searchTableColumns && this.searchTableColumns[this.value.type] === null) {
+ this.ui.columnEmptyInfo.show();
+ } else {
+ this.ui.columnEmptyInfo.hide();
+ }
+ this.fetchCollection(value, _.extend({ 'fromUrl': true }, (this.value && this.value.pageOffset ? { 'next': true } : null)));
+ this.ui.showPage.select2({
+ data: _.sortBy(_.union([25, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500], [this.limit])),
+ tags: true,
+ dropdownCssClass: "number-input",
+ multiple: false
+ });
+ if (this.value && this.value.pageLimit) {
+ this.ui.showPage.val(this.limit).trigger('change', { "skipViewChange": true });
+ }
+ }
+ },
+ getColumnOrderWithPosition: function() {
+ var that = this;
+ return _.map(that.columnOrder, function(value, key) {
+ return key + "::" + value;
+ }).join(",");
+ },
+ triggerUrl: function(options) {
+ Utils.setUrl(_.extend({
+ url: Utils.getUrlState.getQueryUrl().queyParams[0],
+ urlParams: this.columnOrder ? _.extend(this.value, { 'uiParameters': this.getColumnOrderWithPosition() }) : this.value,
+ mergeBrowserUrl: false,
+ trigger: false,
+ updateTabState: true
+ }, options));
+ },
+ updateColumnList: function(updatedList) {
+ if (updatedList) {
+ var listOfColumns = [];
+ _.map(updatedList, function(obj) {
+ var key = obj.name;
+ if (obj.renderable) {
+ listOfColumns.push(obj.name);
+ }
+ });
+ listOfColumns = _.sortBy(listOfColumns);
+ this.value.attributes = listOfColumns.length ? listOfColumns.join(",") : null;
+ if (this.value && this.value.relationshipName && this.searchTableColumns) {
+ this.searchTableColumns[this.value.relationshipName] = listOfColumns.length ? listOfColumns : null;
+ }
+ } else if (this.value && this.value.relationshipName && this.searchTableColumns && this.value.attributes) {
+ this.searchTableColumns[this.value.relationshipName] = this.value.attributes.split(",");
+ }
+ },
+ fetchCollection: function(value, options) {
+ var that = this,
+ isPostMethod = (this.value && this.value.searchType === "basic"),
+ isRelationTab = Utils.getUrlState.isRelationTab(),
+ relationshipFilter = null;
+ if (isRelationTab) {
+ relationshipFilter = CommonViewFunction.attributeFilter.generateAPIObj(this.value.relationshipFilters);
+ }
+ if (isPostMethod && isRelationTab) {
+ var excludeDefaultColumn = (this.value.relationshipName && this.searchTableColumns) ? _.difference(this.searchTableColumns[this.value.relationshipName], this.defaultColumns) : null,
+ filterObj = {
+ 'relationshipFilters': relationshipFilter,
+ 'attributes': excludeDefaultColumn ? excludeDefaultColumn : null
+ };
+ }
+ this.showLoader();
+ if (Globals.searchApiCallRef && Globals.searchApiCallRef.readyState === 1) {
+ Globals.searchApiCallRef.abort();
+ }
+ var apiObj = {
+ skipDefaultError: true,
+ sort: false,
+ success: function(dataOrCollection, response) {
+ if (that.isDestroyed) {
+ return;
+ }
+ Globals.searchApiCallRef = undefined;
+ var isFirstPage = that.offset === 0,
+ dataLength = 0,
+ goToPage = that.ui.gotoPage.val();
+ that.ui.gotoPage.val('');
+ that.ui.gotoPage.parent().removeClass('has-error');
+ that.ui.gotoPagebtn.prop("disabled", true);
+ if (!(that.ui.pageRecordText instanceof jQuery)) {
+ return;
+ }
+ if (isPostMethod && dataOrCollection && dataOrCollection.relations) {
+ dataLength = dataOrCollection.relations.length;
+ } else {
+ dataLength = dataOrCollection.length;
+ }
+
+ if (!dataLength && that.offset >= that.limit && ((options && options.next) || goToPage) && (options && !options.fromUrl)) {
+ /* User clicks on next button and server returns
+ empty response then disabled the next button without rendering table*/
+
+ that.hideLoader();
+ var pageNumber = that.activePage + 1;
+ if (goToPage) {
+ pageNumber = goToPage;
+ that.offset = (that.activePage - 1) * that.limit;
+ } else {
+ that.finalPage = that.activePage;
+ that.ui.nextData.attr('disabled', true);
+ that.offset = that.offset - that.limit;
+ }
+ if (that.value) {
+ that.value.pageOffset = that.offset;
+ that.triggerUrl();
+ }
+ Utils.notifyInfo({
+ html: true,
+ content: Messages.search.noRecordForPage + '<b>' + Utils.getNumberSuffix({ number: pageNumber, sup: true }) + '</b> page'
+ });
+ return;
+ }
+ if (isPostMethod) {
+ that.searchCollection.reset(dataOrCollection.relations, { silent: true });
+ that.searchCollection.fullCollection.reset(dataOrCollection.relations, { silent: true });
+ }
+
+ /*Next button check.
+ It's outside of Previous button else condition
+ because when user comes from 2 page to 1 page than we need to check next button.*/
+ if (dataLength < that.limit) {
+ that.ui.nextData.attr('disabled', true);
+ } else {
+ that.ui.nextData.attr('disabled', false);
+ }
+
+ if (isFirstPage && (!dataLength || dataLength < that.limit)) {
+ that.ui.paginationDiv.hide();
+ } else {
+ that.ui.paginationDiv.show();
+ }
+
+ // Previous button check.
+ if (isFirstPage) {
+ that.ui.previousData.attr('disabled', true);
+ that.pageFrom = 1;
+ that.pageTo = that.limit;
+ } else {
+ that.ui.previousData.attr('disabled', false);
+ }
+
+ if (options && options.next) {
+ //on next click, adding "1" for showing the another records.
+ that.pageTo = that.offset + that.limit;
+ that.pageFrom = that.offset + 1;
+ } else if (!isFirstPage && options && options.previous) {
+ that.pageTo = that.pageTo - that.limit;
+ that.pageFrom = (that.pageTo - that.limit) + 1;
+ }
+ that.ui.pageRecordText.html("Showing <u>" + that.searchCollection.models.length + " records</u> From " + that.pageFrom + " - " + that.pageTo);
+ that.activePage = Math.round(that.pageTo / that.limit);
+ that.ui.activePage.attr('title', "Page " + that.activePage);
+ that.ui.activePage.text(that.activePage);
+ that.renderTableLayoutView();
+ that.multiSelectEntity = [];
+
+ if (dataLength > 0) {
+ that.$('.searchTable').removeClass('noData')
+ }
+
+ if (Utils.getUrlState.isRelationSearch() && value) {
+ var isCapsuleView = true;
+ var searchString = '<span class="filterQuery">' + CommonViewFunction.generateQueryOfFilter(that.value, isCapsuleView) + "</span>";
+ that.$('.searchResult').html(searchString);
+ }
+ },
+ silent: true,
+ reset: true
+ }
+ if (value) {
+ if (value.searchType) {
+ this.searchCollection.url = UrlLinks.relationshipSearchApiUrl(value.searchType);
+ }
+ _.extend(this.searchCollection.queryParams, { 'limit': this.limit, 'offset': this.offset, 'query': _.trim(value.query), 'relationshipName': value.relationshipName || null });
+ if (isPostMethod) {
+ this.searchCollection.filterObj = _.extend({}, filterObj);
+ apiObj['data'] = _.extend(filterObj, _.pick(this.searchCollection.queryParams, 'query', 'limit', 'offset', 'relationshipName'));
+ Globals.searchApiCallRef = this.searchCollection.getBasicRearchResult(apiObj);
+ } else {
+ apiObj.data = null;
+ this.searchCollection.filterObj = null;
+ Globals.searchApiCallRef = this.searchCollection.fetch(apiObj);
+ }
+ } else {
+ _.extend(this.searchCollection.queryParams, { 'limit': this.limit, 'offset': this.offset });
+ if (isPostMethod) {
+ apiObj['data'] = _.extend(filterObj, _.pick(this.searchCollection.queryParams, 'query', 'limit', 'offset', 'relationshipName'));
+ Globals.searchApiCallRef = this.searchCollection.getBasicRearchResult(apiObj);
+ } else {
+ apiObj.data = null;
+ Globals.searchApiCallRef = this.searchCollection.fetch(apiObj);
+ }
+ }
+ },
+ tableRender: function(options) {
+ var that = this,
+ savedColumnOrder = options.order,
+ TableLayout = options.table,
+ columnCollection = Backgrid.Columns.extend({
+ sortKey: "displayOrder",
+ className: "my-awesome-css-animated-grid",
+ comparator: function(item) {
+ return item.get(this.sortKey) || 999;
+ },
+ setPositions: function() {
+ _.each(this.models, function(model, index) {
+ model.set("displayOrder", (savedColumnOrder == null ? index : parseInt(savedColumnOrder[model.get('label')])) + 1, { silent: true });
+ });
+ return this;
+ }
+ });
+ var columns = new columnCollection((that.searchCollection.dynamicTable ? that.getDaynamicColumns(that.searchCollection.toJSON()) : that.getFixedDslColumn()));
+ columns.setPositions().sort();
+ var table = new TableLayout(_.extend({}, that.commonTableOptions, {
+ columns: columns
+ }));
+ if (table.collection.length === 0) {
+ that.$(".searchTable").addClass('noData');
+ }
+ if (!that.REntityTableLayoutView) {
+ return;
+ }
+ if (!that.value) {
+ that.value = that.options.value;
+ }
+ that.REntityTableLayoutView.show(table);
+ that.$(".ellipsis-with-margin .inputAssignTag").hide();
+ table.trigger("grid:refresh"); /*Event fire when table rendered*/
+ // that.REntityTableLayoutView.$el.find('.colSort thead tr th:not(:first)').addClass('dragHandler');
+ if (that.isTableDropDisable !== true) {
+ var tableDropFunction = function(from, to, el) {
+ tableDragger(document.querySelector(".colSort")).destroy();
+ that.columnOrder = that.getColumnOrder(el.querySelectorAll('th.renderable'));
+ that.triggerUrl();
+ that.tableRender({ "order": that.columnOrder, "table": TableLayout });
+ that.checkTableFetch();
+ }
+ that.REntityTableLayoutView.$el.find('.colSort thead tr th:not(.select-all-header-cell)').addClass('dragHandler');
+ tableDragger(document.querySelector(".colSort"), { dragHandler: ".dragHandler" }).on('drop', tableDropFunction);
+ }
+ },
+ renderTableLayoutView: function(col) {
+ var that = this;
+ require(['utils/TableLayout'], function(TableLayout) {
+ // displayOrder added for column manager
+ if (that.value.uiParameters) {
+ var savedColumnOrder = _.object(that.value.uiParameters.split(',').map(function(a) {
+ return a.split('::');
+ })); // get Column position from string to object
+ }
+
+ that.tableRender({ "order": savedColumnOrder, "table": TableLayout });
+ that.checkTableFetch();
+ });
+ },
+ getColumnOrder: function(arr) {
+ var obj = {};
+ for (var i = 0; i < arr.length; ++i) {
+ var innerText = arr[i].innerText.trim();
+ obj[(innerText == "" ? 'Select' : innerText)] = i;
+ }
+ return obj;
+ },
+ checkTableFetch: function() {
+ if (this.asyncFetchCounter <= 0) {
+ this.hideLoader();
+ Utils.generatePopover({
+ el: this.$('[data-id="showMoreLess"]'),
+ contentClass: 'popover-tag-term',
+ viewFixedPopover: true,
+ popoverOptions: {
+ container: null,
+ content: function() {
+ return $(this).find('.popup-tag-term').children().clone();
+ }
+ }
+ });
+ }
+ },
+ getFixedDslColumn: function() {
+ var that = this,
+ nameCheck = 0,
+ columnToShow = null,
+ col = {};
+ this.value = Utils.getUrlState.getQueryParams() || this.value;
+ if (this.value && this.value.searchType === "basic" && this.searchTableColumns && (this.searchTableColumns[this.value.relationshipName] !== undefined)) {
+ columnToShow = this.searchTableColumns[this.value.relationshipName] == null ? [] : this.searchTableColumns[this.value.relationshipName];
+ }
+ col['name'] = {
+ label: "Guid",
+ cell: "html",
+ editable: false,
+ resizeable: true,
+ orderable: false,
+ renderable: true,
+ className: "searchTableName",
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var obj = model.toJSON(),
+ nameHtml = "",
+ name = Utils.getName(obj),
+ img = "";
+ if (obj.guid) {
+ if (obj.guid == "-1") {
+ nameHtml = '<span title="' + name + '">' + name + '</span>';
+ } else {
+ nameHtml = '<a title="' + name + '" href="#!/relationshipDetailPage/' + obj.guid + (that.fromView ? "?from=" + that.fromView : "") + '">' + name + '</a>';
+ }
+ } else {
+ nameHtml = '<span title="' + name + '">' + name + '</span>';
+ }
+ img = "<div><img data-imgGuid='" + obj.guid + "' src='/img/entity-icon/table.png'></div>";
+ if (obj.status && Enums.entityStateReadOnly[obj.status]) {
+ nameHtml += '<button type="button" title="Deleted" class="btn btn-action btn-md deleteBtn"><i class="fa fa-trash"></i></button>';
+ nameHtml = '<div class="readOnly readOnlyLink">' + nameHtml + '</div>';
+ img = "<div><img data-imgGuid='" + obj.guid + "' src='/img/entity-icon/disabled/table.png'></div>";
+ }
+ return (img + nameHtml);
+ }
+ })
+ };
+ if (this.value) {
+ col['typeName'] = {
+ label: "Type",
+ cell: "Html",
+ editable: false,
+ resizeable: true,
+ orderable: true,
+ renderable: (columnToShow ? _.contains(columnToShow, 'typeName') : true),
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var obj = model.toJSON();
+ if (obj && obj.typeName) {
+ return '<span>' + obj.typeName + '</span>';
+ }
+ }
+ })
+ };
+ col['end1'] = {
+ label: "End1",
+ cell: "Html",
+ editable: false,
+ resizeable: true,
+ orderable: true,
+ renderable: (columnToShow ? _.contains(columnToShow, 'end1') : true),
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var obj = model.toJSON();
+ if (obj && obj.end1) {
+ var key, uniqueAttributesValue;
+ for (key in obj.end1.uniqueAttributes) {
+ uniqueAttributesValue = obj.end1.uniqueAttributes[key];
+ }
+ uniqueAttributesValue = uniqueAttributesValue ? uniqueAttributesValue : obj.end1.guid;
+ return '<a title="' + uniqueAttributesValue + '" href="#!/detailPage/' + obj.end1.guid + '?from=relationshipSearch">' + uniqueAttributesValue + '</a>';
+ }
+ }
+ })
+ };
+ col['end2'] = {
+ label: "End2",
+ cell: "Html",
+ editable: false,
+ resizeable: true,
+ orderable: true,
+ renderable: (columnToShow ? _.contains(columnToShow, 'end2') : true),
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var obj = model.toJSON();
+ if (obj && obj.end2) {
+ var key, uniqueAttributesValue;
+ for (key in obj.end2.uniqueAttributes) {
+ uniqueAttributesValue = obj.end2.uniqueAttributes[key];
+ }
+ uniqueAttributesValue = uniqueAttributesValue ? uniqueAttributesValue : obj.end2.guid;
+ return '<a title="' + uniqueAttributesValue + '" href="#!/detailPage/' + obj.end2.guid + '?from=relationshipSearch">' + uniqueAttributesValue + '</a>';
+ }
+ }
+ })
+ };
+ col['label'] = {
+ label: "Label",
+ cell: "Html",
+ editable: false,
+ resizeable: true,
+ orderable: true,
+ renderable: (columnToShow ? _.contains(columnToShow, 'label') : true),
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var obj = model.toJSON();
+ if (obj) {
+ return "<span>" + obj.label + "</span>"
+ }
+ }
+ })
+ };
+
+ if (this.value && this.value.searchType === "basic") {
+ var def = this.relationshipDefCollection.fullCollection.find({ name: this.value.relationshipName });
+ if (def) {
+ var attrObj = def ? Utils.getNestedSuperTypeObj({ data: def.toJSON(), collection: this.relationshipDefCollection, attrMerge: true }) : [];
+ _.each(attrObj, function(obj, key) {
+ var key = obj.name,
+ isRenderable = _.contains(columnToShow, key),
+ isSortable = obj.typeName.search(/(array|map)/i) == -1;
+ col[obj.name] = {
+ label: obj.name.capitalize(),
+ cell: "Html",
+ headerCell: Backgrid.HeaderHTMLDecodeCell,
+ editable: false,
+ resizeable: true,
+ orderable: true,
+ sortable: isSortable,
+ renderable: isRenderable,
+ headerClassName: "",
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var modelObj = model.toJSON();
+ if (modelObj && modelObj.attributes && !_.isUndefined(modelObj.attributes[key])) {
+ var tempObj = {
+ 'scope': that,
+ 'attributeDefs': [obj],
+ 'valueObject': {},
+ 'isTable': false
+ };
+ tempObj.valueObject[key] = modelObj.attributes[key];
+ var tablecolumn = CommonViewFunction.propertyTable(tempObj);
+ if (_.isArray(modelObj.attributes[key])) {
+ var column = $("<div>" + tablecolumn + "</div>")
+ if (tempObj.valueObject[key].length > 2) {
+ column.addClass("toggleList semi-collapsed").append("<span><a data-id='load-more-columns'>Show More</a></span>");
+ }
+ return column;
+ }
+ return tablecolumn;
+ }
+ }
+ })
+ };
+ });
+ }
+ }
+ }
+ return this.searchCollection.constructor.getTableCols(col, this.searchCollection);
+ },
+ getDaynamicColumns: function(valueObj) {
+ var that = this,
+ col = {};
+ if (valueObj && valueObj.length) {
+ var firstObj = _.first(valueObj);
+ _.each(_.keys(firstObj), function(key) {
+ col[key] = {
+ label: key.capitalize(),
+ cell: "Html",
+ editable: false,
+ resizeable: true,
+ orderable: true,
+ formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
+ fromRaw: function(rawValue, model) {
+ var modelObj = model.toJSON();
+ if (key == "name") {
+ var nameHtml = "",
+ name = _.escape(modelObj[key]);
+ if (modelObj.guid) {
+ nameHtml = '<a title="' + name + '" href="#!/detailPage/' + modelObj.guid + (that.fromView ? "?from=" + that.fromView : "") + '">' + name + '</a>';
+ } else {
+ nameHtml = '<span title="' + name + '">' + name + '</span>';
+ }
+ return nameHtml;
+ } else if (modelObj && !_.isUndefined(modelObj[key])) {
+ var tempObj = {
+ 'scope': that,
+ 'valueObject': {},
+ 'isTable': false
+ };
+ tempObj.valueObject[key] = modelObj[key];
+ return CommonViewFunction.propertyTable(tempObj);
+ }
+ }
+ })
+ };
+ });
+ }
+ return this.searchCollection.constructor.getTableCols(col, this.searchCollection);
+ },
+ showLoader: function() {
+ this.$('.fontLoader:not(.for-ignore)').addClass('show');
+ this.$('.tableOverlay').addClass('show');
+ },
+ hideLoader: function(options) {
+ this.$('.fontLoader:not(.for-ignore)').removeClass('show');
+ this.$('.ellipsis-with-margin').show();
+ options && options.type === 'error' ? $('.pagination-box').hide() : this.$('.pagination-box').show(); // only show for first time and hide when type is error
+ this.$('.tableOverlay').removeClass('show');
+ },
+ onClicknextData: function() {
+ this.offset = this.offset + this.limit;
+ _.extend(this.searchCollection.queryParams, {
+ offset: this.offset
+ });
+ if (this.value) {
+ this.value.pageOffset = this.offset;
+ this.triggerUrl();
+ }
+ this.fetchCollection(null, {
+ next: true
+ });
+ },
+ onClickpreviousData: function() {
+ this.offset = this.offset - this.limit;
+ if (this.offset <= -1) {
+ this.offset = 0;
+ }
+ _.extend(this.searchCollection.queryParams, {
+ offset: this.offset
+ });
+ if (this.value) {
+ this.value.pageOffset = this.offset;
+ this.triggerUrl();
+ }
+ this.fetchCollection(null, {
+ previous: true
+ });
+ },
+ changePageLimit: function(e, obj) {
+ if (!obj || (obj && !obj.skipViewChange)) {
+ var limit = parseInt(this.ui.showPage.val());
+ if (limit == 0) {
+ this.ui.showPage.data('select2').$container.addClass('has-error');
+ return;
+ } else {
+ this.ui.showPage.data('select2').$container.removeClass('has-error');
+ }
+ this.limit = limit;
+ this.offset = 0;
+ if (this.value) {
+ this.value.pageLimit = this.limit;
+ this.value.pageOffset = this.offset;
+ this.triggerUrl();
+ }
+ _.extend(this.searchCollection.queryParams, { limit: this.limit, offset: this.offset });
+ this.fetchCollection();
+ }
+ },
+ gotoPagebtn: function(e) {
+ var that = this;
+ var goToPage = parseInt(this.ui.gotoPage.val());
+ if (!(_.isNaN(goToPage) || goToPage <= -1)) {
+ if (this.finalPage && this.finalPage < goToPage) {
+ Utils.notifyInfo({
+ html: true,
+ content: Messages.search.noRecordForPage + '<b>' + Utils.getNumberSuffix({ number: goToPage, sup: true }) + '</b> page'
+ });
+ return;
+ }
+ this.offset = (goToPage - 1) * this.limit;
+ if (this.offset <= -1) {
+ this.offset = 0;
+ }
+ _.extend(this.searchCollection.queryParams, { limit: this.limit, offset: this.offset });
+ if (this.offset == (this.pageFrom - 1)) {
+ Utils.notifyInfo({
+ content: Messages.search.onSamePage
+ });
+ } else {
+ if (this.value) {
+ this.value.pageOffset = this.offset;
+ this.triggerUrl();
+ }
+ // this.offset is updated in gotoPagebtn function so use next button calculation.
+ this.fetchCollection(null, { 'next': true });
+ }
+ }
+ }
+ });
+ return RelationSearchResultLayoutView;
+});
\ No newline at end of file
diff --git a/dashboardv3/public/js/views/search/SearchDefaultLayoutView.js b/dashboardv3/public/js/views/search/SearchDefaultLayoutView.js
index b65f753d0..340351e8c 100644
--- a/dashboardv3/public/js/views/search/SearchDefaultLayoutView.js
+++ b/dashboardv3/public/js/views/search/SearchDefaultLayoutView.js
@@ -31,7 +31,8 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
RGlobalSearchLayoutView: "#r_globalSearchLayoutView",
RSearchResultLayoutView: "#r_searchResultLayoutView",
RQueryBuilderEntity: "#r_attributeQueryBuilderEntity",
- RQueryBuilderClassification: "#r_attributeQueryBuilderClassification"
+ RQueryBuilderClassification: "#r_attributeQueryBuilderClassification",
+ RQueryBuilderRelationship: '#r_attributeQueryBuilderRelationship'
},
/** ui selector cache */
@@ -42,14 +43,17 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
attrClose: "[data-id='attrClose']",
entityRegion: "[data-id='entityRegion']",
classificationRegion: "[data-id='classificationRegion']",
+ relationshipRegion: "[data-id='relationshipRegion']",
checkDeletedEntity: "[data-id='checkDeletedEntity']",
checkSubClassification: "[data-id='checkSubClassification']",
checkSubType: "[data-id='checkSubType']",
entityName: ".entityName",
+ relationshipName: ".relationshipName",
classificationName: ".classificationName",
createNewEntity: '[data-id="createNewEntity"]',
clearQuerySearch: "[data-id='clearQuerySearch']",
- refreshSearchQuery: "[data-id='refreshSearchResult']"
+ refreshSearchQuery: "[data-id='refreshSearchResult']",
+ includeExclude : "[data-id='includeExclude']"
},
/** ui events hash */
events: function() {
@@ -67,7 +71,12 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
};
events["click " + this.ui.refreshSearchQuery] = function(e) {
- this.options.searchVent.trigger('search:refresh');
+ if (Utils.getUrlState.isSearchTab()) {
+ this.options.searchVent.trigger('search:refresh');
+ }
+ if(Utils.getUrlState.isRelationTab()){
+ this.options.searchVent.trigger('relationSearch:refresh');
+ }
this.disableRefreshButton();
};
@@ -88,11 +97,13 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
switch (type) {
case "entityFilters":
- that.filtersQueryUpdate(e, false);
+ that.filtersQueryUpdate(e, false, false);
break;
case "tagFilters":
- that.filtersQueryUpdate(e, true);
+ that.filtersQueryUpdate(e, true, false);
break;
+ case "relationshipFilters":
+ that.filtersQueryUpdate(e, false, true);
default:
this.options.value[type] = null;
}
@@ -137,6 +148,7 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
this.hidenFilter = false;
this.tagAttributeLength = 0;
this.entityAttributeLength = 0;
+ this.relationshipAttributeLength = 0;
this.tagEntityCheck = false;
this.typeEntityCheck = false;
},
@@ -144,15 +156,21 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
onRender: function() {
this.toggleLayoutClass = this.$(".col-sm-9.f-right, .col-sm-12.f-right");
this.renderGlobalSearch();
- this.renderSearchResult();
+ if (!Utils.getUrlState.isRelationSearch()) {
+ this.renderSearchResult();
+ }
+ if (Utils.getUrlState.isRelationSearch()) {
+ this.renderRelationSearchResult();
+ }
this.updateView();
this.ui.entityRegion.hide();
this.ui.classificationRegion.hide();
+ this.ui.relationshipRegion.hide();
},
- filtersQueryUpdate: function(e, isTag) {
- var filters = CommonViewFunction.attributeFilter.extractUrl({ "value": isTag ? this.options.value.tagFilters : this.options.value.entityFilters, "formatDate": true }),
+ filtersQueryUpdate: function(e, isTag, isRelationship) {
+ var filters = CommonViewFunction.attributeFilter.extractUrl({ "value": isTag ? this.options.value.tagFilters : (isRelationship ? this.options.value.relationshipFilters : this.options.value.entityFilters), "formatDate": true }),
rules = filters.rules,
- filtertype = isTag ? "tagFilters" : "entityFilters",
+ filtertype = isTag ? "tagFilters" : (isRelationship ? "relationshipFilters" : "entityFilters"),
that = this;
filters.rules = _.filter(rules, function(obj, key) {
@@ -162,8 +180,10 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
that.updateFilterOptions(filters, filtertype, isTag);
}
if (filters.rules.length == 0) {
- if (isTag) {
+ if (isTag && !isRelationship) {
this.options.searchTableFilters["tagFilters"][that.options.value.tag] = "";
+ } else if (isRelationship) {
+ this.options.searchTableFilters["relationshipFilters"][that.options.value.relationshipName] = "";
} else {
this.options.searchTableFilters["entityFilters"][that.options.value.type] = "";
}
@@ -222,7 +242,12 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
_.extend(this.options, options);
this.updateView();
this.onClickAttrFilter();
- this.renderSearchResult();
+ if (!Utils.getUrlState.isRelationSearch()) {
+ this.renderSearchResult();
+ }
+ if (Utils.getUrlState.isRelationSearch()) {
+ this.renderRelationSearchResult();
+ }
},
renderGlobalSearch: function() {
var that = this;
@@ -237,6 +262,12 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
that.RSearchResultLayoutView.show(new SearchResultLayoutView(that.options));
});
},
+ renderRelationSearchResult: function() {
+ var that = this;
+ require(["views/search/RelationSearchResultLayoutView"], function(RelationSearchResultLayoutView) {
+ that.RSearchResultLayoutView.show(new RelationSearchResultLayoutView(that.options));
+ });
+ },
checkEntityFilter: function(options) {
if (options && options.value) {
if (options.value.type && options.value.entityFilters) {
@@ -252,12 +283,14 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
var that = this,
obj = {
value: that.options.value,
+ relationship: Utils.getUrlState.isRelationSearch() ? true : false,
searchVent: that.options.searchVent,
entityDefCollection: that.options.entityDefCollection,
enumDefCollection: that.options.enumDefCollection,
typeHeaders: that.options.typeHeaders,
classificationDefCollection: that.options.classificationDefCollection,
businessMetadataDefCollection: that.options.businessMetadataDefCollection,
+ relationshipDefCollection: that.options.relationshipDefCollection,
searchTableFilters: that.checkEntityFilter(that.options)
};
this.tagEntityCheck = false;
@@ -280,6 +313,7 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
}
if (that.options.value.tag) {
this.ui.classificationRegion.show();
+ this.ui.includeExclude.show();
// this.ui.entityRegion.hide();
var attrTagObj = that.options.classificationDefCollection.fullCollection.find({ name: that.options.value.tag });
if (attrTagObj) {
@@ -303,6 +337,7 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
}
if (that.options.value.type) {
this.ui.entityRegion.show();
+ this.ui.includeExclude.show();
var attrTypeObj = that.options.entityDefCollection.fullCollection.find({ name: that.options.value.type });
if (attrTypeObj) {
attrTypeObj = Utils.getNestedSuperTypeObj({
@@ -324,11 +359,33 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
this.ui.entityName.html(_.escape(that.options.value.type));
}
+ if (that.options.value.relationshipName) {
+ this.ui.relationshipRegion.show();
+ this.ui.includeExclude.hide();
+ var attrTypeObj = that.options.relationshipDefCollection.fullCollection.find({ name: that.options.value.relationshipName });
+ if (attrTypeObj) {
+ attrTypeObj = Utils.getNestedSuperTypeObj({
+ data: attrTypeObj.toJSON(),
+ collection: that.options.relationshipDefCollection,
+ attrMerge: true
+ });
+ this.relationshipAttributeLength = attrTypeObj.length;
+ }
+ this.renderQueryBuilder(_.extend({}, obj, {
+ tag: false,
+ type: false,
+ relation: true,
+ attrObj: attrTypeObj
+ }), this.RQueryBuilderRelationship);
+
+ this.ui.relationshipName.html(_.escape(that.options.value.relationshipName));
+ }
}
},
okAttrFilterButton: function(e) {
var isTag,
+ isRelationship,
filtertype,
queryBuilderRef,
isFilterValidate = true,
@@ -350,6 +407,15 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
searchAttribute();
}
}
+ if (this.options.value.relationshipName) {
+ isTag = false;
+ isRelationship = true;
+ filtertype = "relationshipFilters";
+ if (this.relationshipAttributeLength !== 0) {
+ queryBuilderRef = this.RQueryBuilderRelationship.currentView.ui.builder;
+ searchAttribute();
+ }
+ }
filterPopupStatus();
function searchAttribute() {
@@ -407,13 +473,23 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
updateFilterOptions: function(rule, filtertype, isTag) {
var that = this,
ruleUrl = CommonViewFunction.attributeFilter.generateUrl({ value: rule, formatedDateToLong: true });
- this.options.searchTableFilters[filtertype][isTag ? this.options.value.tag : this.options.value.type] = ruleUrl;
+ if (filtertype === "relationshipFilters") {
+ this.options.searchTableFilters[filtertype][this.options.value.relationshipName] = ruleUrl;
+ } else {
+ this.options.searchTableFilters[filtertype][isTag ? this.options.value.tag : this.options.value.type] = ruleUrl;
+ }
if (!isTag && this.options.value && this.options.value.type && this.options.searchTableColumns) {
if (!this.options.searchTableColumns[this.options.value.type]) {
this.options.searchTableColumns[this.options.value.type] = ["selected", "name", "description", "typeName", "owner", "tag", "term"];
}
this.options.searchTableColumns[this.options.value.type] = _.sortBy(_.union(_.without(this.options.searchTableColumns[this.options.value.type]), this.getIdFromRuleObj(rule)));
}
+ if (!isTag && this.options.value && this.options.value.relationshipName && this.options.searchTableColumns) {
+ if (!this.options.searchTableColumns[this.options.value.relationshipName]) {
+ this.options.searchTableColumns[this.options.value.relationshipName] = ["name", "typeName", "end1", "end2", "label"];
+ }
+ this.options.searchTableColumns[this.options.value.relationshipName] = _.sortBy(_.union(this.options.searchTableColumns[this.options.value.relationshipName], this.getIdFromRuleObj(rule)));
+ }
},
renderQueryBuilder: function(obj, rQueryBuilder) {
var that = this;
@@ -423,17 +499,19 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
},
searchAttrFilter: function() {
var selectedNodeId,
- name = this.options.value.type || this.options.value.tag,
+ name = this.options.value.type || this.options.value.tag || this.options.value.relationshipName,
typeValue,
tagValue,
termValue,
entityFilterObj = this.options.searchTableFilters["entityFilters"],
tagFilterObj = this.options.searchTableFilters["tagFilters"],
+ relationshipFilterObj = this.options.searchTableFilters["relationshipFilters"],
params = {
searchType: "basic",
dslChecked: false,
tagFilters: null,
entityFilters: null,
+ relationshipFilterObj: null,
query: null,
type: null,
tag: null,
@@ -452,6 +530,9 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
if (this.options.value.type) {
params["type"] = this.options.value.type;
}
+ if (this.options.value.relationshipName) {
+ params["relationshipName"] = this.options.value.relationshipName;
+ }
if (this.options.value.term) {
params["term"] = this.options.value.term;
}
@@ -472,6 +553,9 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
if (tagFilterObj) {
params['tagFilters'] = tagFilterObj[this.options.value.tag];
}
+ if (relationshipFilterObj) {
+ params['relationshipFilters'] = relationshipFilterObj[this.options.value.relationshipName]
+ }
params["pageOffset"] = 0;
if (!this.options.value.tag && !this.options.value.type && !this.options.value.term && !this.options.value.query) {
@@ -487,6 +571,9 @@ define(["require", "backbone", "utils/Globals", "hbs!tmpl/search/SearchDefaultLa
} else {
updatedUrl = '#!/search/searchResult';
}
+ if (this.options.value.relationshipName) {
+ updatedUrl = '#!/relationship/relationshipSearchResult';
+ }
Utils.setUrl({
url: updatedUrl,
urlParams: _.extend({}, params),
diff --git a/dashboardv3/public/js/views/search/SearchFilterBrowseLayoutView.js b/dashboardv3/public/js/views/search/SearchFilterBrowseLayoutView.js
index 86916f45d..c81a74fd8 100644
--- a/dashboardv3/public/js/views/search/SearchFilterBrowseLayoutView.js
+++ b/dashboardv3/public/js/views/search/SearchFilterBrowseLayoutView.js
@@ -37,7 +37,8 @@ define([
RClassificationTreeRender: '[data-id="r_classificationTreeRender"]',
REntityTreeRender: '[data-id="r_entityTreeRender"]',
RCustomFilterTreeRender: '[data-id="r_customFilterTreeRender"]',
- RBusinessMetadataTreeRender: '[data-id="r_businessMetadataTreeRender"]'
+ RBusinessMetadataTreeRender: '[data-id="r_businessMetadataTreeRender"]',
+ RRelationshipTreeRender: '[data-id="r_relationshipTreeRender"]'
},
ui: {
searchNode: '[data-id="searchNode"]',
@@ -74,6 +75,7 @@ define([
this.termSearchTree = this.$('[data-id="termSearchTree"]');
this.customFilterSearchTree = this.$('[data-id="customFilterSearchTree"]');
this.businessMetadataSearchTree = this.$('[data-id="businessMetadataSearchTree"]');
+ this.RelationshipSearchTree = this.$('[data-id="relationshipSearchTree"]');
this.entitySearchTree.jstree(true).show_all();
this.entitySearchTree.jstree("search", searchString);
this.classificationSearchTree.jstree(true).show_all();
@@ -106,6 +108,7 @@ define([
"entityDefCollection",
"enumDefCollection",
"classificationDefCollection",
+ "relationshipDefCollection",
"searchTableColumns",
"searchTableFilters",
"metricCollection",
@@ -121,6 +124,7 @@ define([
this.renderGlossaryTree(opt);
this.renderCustomFilterTree();
this.renderBusinessMetadataTree();
+ this.renderRelationshipTree();
this.showHideGlobalFilter();
this.showDefaultPage();
},
@@ -211,6 +215,9 @@ define([
if (this.REntityTreeRender.currentView) {
this.REntityTreeRender.currentView.manualRender(this.options);
}
+ if (this.RRelationshipTreeRender.currentView) {
+ this.RRelationshipTreeRender.currentView.manualRender(this.options);
+ }
}
},
renderEntityTree: function(opt) {
@@ -242,6 +249,12 @@ define([
require(["views/search/tree/BusinessMetadataTreeLayoutView"], function(BusinessMetadataTreeLayoutView) {
that.RBusinessMetadataTreeRender.show(new BusinessMetadataTreeLayoutView(_.extend({ query: that.query }, that.options)));
});
+ },
+ renderRelationshipTree: function(){
+ var that = this;
+ require(["views/search/tree/RelationshipSearchTreeLayoutView"], function(RelationshipSearchTreeLayoutView) {
+ that.RRelationshipTreeRender.show(new RelationshipSearchTreeLayoutView(_.extend({ query: that.query }, that.options)));
+ });
}
});
return SearchFilterBrowseLayoutViewNew;
diff --git a/dashboardv3/public/js/views/search/SearchQueryView.js b/dashboardv3/public/js/views/search/SearchQueryView.js
index 1f658e436..6434234a5 100644
--- a/dashboardv3/public/js/views/search/SearchQueryView.js
+++ b/dashboardv3/public/js/views/search/SearchQueryView.js
@@ -51,7 +51,7 @@ define(['require',
* @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', 'tag', 'searchTableFilters', 'relationshipDefCollection', 'relationship'));
this.bindEvents();
var that = this;
this.modal = new Modal({
@@ -104,6 +104,16 @@ define(['require',
if (Globals[this.value.tag]) {
obj['attrObj'] = Globals[this.value.tag].attributeDefs;
}
+ } else if (this.relationship) {
+ obj['relationship'] = true;
+ obj['attrObj'] = this.relationshipDefCollection.fullCollection.find({ name: this.value.relationshipName });
+ if(obj.attrObj){
+ obj.attrObj = Utils.getNestedSuperTypeObj({
+ data: obj.attrObj.toJSON(),
+ collection: this.relationshipDefCollection,
+ attrMerge: true,
+ });
+ }
} else {
obj['type'] = true;
obj['attrObj'] = this.entityDefCollection.fullCollection.find({ name: this.value.type });
diff --git a/dashboardv3/public/js/views/search/save/SaveModalLayoutView.js b/dashboardv3/public/js/views/search/save/SaveModalLayoutView.js
index 6e6e64990..7362ec718 100644
--- a/dashboardv3/public/js/views/search/save/SaveModalLayoutView.js
+++ b/dashboardv3/public/js/views/search/save/SaveModalLayoutView.js
@@ -49,13 +49,17 @@ define(['require',
},
initialize: function(options) {
var that = this;
- _.extend(this, _.pick(options, 'rename', 'selectedModel', 'collection', 'getValue', 'isBasic', 'saveObj'));
+ _.extend(this, _.pick(options, 'rename', 'selectedModel', 'collection', 'getValue', 'isBasic', 'saveObj', 'isRelationship'));
this.model = new VSearch();
this.saveSearchCollection = new VSearchList();
this.saveSearchCollection.url = UrlLinks.saveSearchApiUrl();
this.saveSearchCollection.fullCollection.comparator = function(model) {
return getModelName(model);
}
+ var title = this.isBasic ? " Basic" : " Advanced";
+ if(this.isRelationship){
+ title = " Relationship";
+ }
function getModelName(model) {
if (model.get('name')) {
@@ -67,7 +71,7 @@ define(['require',
} else {
this.modal = modal = new Modal({
titleHtml: true,
- title: '<span>' + (this.selectedModel && this.rename ? 'Rename' : 'Save') + (this.isBasic ? " Basic" : " Advanced") + ' Custom Filter</span>',
+ title: '<span>' + (this.selectedModel && this.rename ? 'Rename' : 'Save') + title + ' Custom Filter</span>',
content: this,
cancelText: "Cancel",
okCloses: false,
@@ -96,7 +100,11 @@ define(['require',
var that = this;
this.saveSearchCollection.fetch({
success: function(collection, data) {
- that.saveSearchCollection.fullCollection.reset(_.where(data, { searchType: that.isBasic ? "BASIC" : "ADVANCED" }));
+ if(that.isRelationship){
+ that.saveSearchCollection.fullCollection.reset(_.where(data, { searchType: "BASIC_RELATIONSHIP" }));
+ } else {
+ that.saveSearchCollection.fullCollection.reset(_.where(data, { searchType: that.isBasic ? "BASIC" : "ADVANCED" }));
+ }
var options = "";
that.saveSearchCollection.fullCollection.each(function(model) {
options += '<option value="' + model.get("name") + '">' + model.get("name") + '</option>';
@@ -158,6 +166,8 @@ define(['require',
} else {
if (this.isBasic) {
saveObj['searchType'] = "BASIC";
+ } else if(this.isRelationship){
+ saveObj['searchType'] = "BASIC_RELATIONSHIP";
} else {
saveObj['searchType'] = "ADVANCED";
}
diff --git a/dashboardv3/public/js/views/search/tree/ClassificationTreeLayoutView.js b/dashboardv3/public/js/views/search/tree/ClassificationTreeLayoutView.js
index 1883dfbd7..13a5a899d 100644
--- a/dashboardv3/public/js/views/search/tree/ClassificationTreeLayoutView.js
+++ b/dashboardv3/public/js/views/search/tree/ClassificationTreeLayoutView.js
@@ -343,6 +343,7 @@ define([
}
},
onNodeSelect: function(options) {
+ Globals.fromRelationshipSearch = false;
if (this.classificationTreeUpdate) {
this.classificationTreeUpdate = false;
return;
diff --git a/dashboardv3/public/js/views/search/tree/CustomFilterTreeLayoutView.js b/dashboardv3/public/js/views/search/tree/CustomFilterTreeLayoutView.js
index eadd64180..ea7185b35 100644
--- a/dashboardv3/public/js/views/search/tree/CustomFilterTreeLayoutView.js
+++ b/dashboardv3/public/js/views/search/tree/CustomFilterTreeLayoutView.js
@@ -107,9 +107,24 @@ define([
},
this
);
+ this.listenTo(
+ this.saveSearchRelationshipCollection.fullCollection,
+ "reset add change remove",
+ function() {
+ if (this.ui.customFilterSearchTree.jstree(true)) {
+ this.ui.customFilterSearchTree.jstree(true).refresh();
+ } else {
+ this.renderCustomFilterTree();
+ }
+ },
+ this
+ );
this.searchVent.on("Save:Filter", function(data) {
that.saveAs();
})
+ this.searchVent.on("SaveRelationship:Filter", function(data) {
+ that.relationshipSaveAs();
+ });
$('body').on('click', '.customFilterPopoverOptions li', function(e) {
that.$('.customFilterPopoverOptions').popover('hide');
that[$(this).find('a').data('fn') + "CustomFilter"](e)
@@ -124,6 +139,7 @@ define([
"typeHeaders",
"searchVent",
"entityDefCollection",
+ "relationshipDefCollection",
"enumDefCollection",
"classificationDefCollection",
"searchTableColumns",
@@ -134,6 +150,7 @@ define([
this.saveSearchBaiscCollection = new VSearchList();
this.saveSearchCollection = new VSearchList();
this.saveSearchAdvanceCollection = new VSearchList();
+ this.saveSearchRelationshipCollection = new VSearchList();
this.saveSearchCollection.url = UrlLinks.saveSearchApiUrl();
this.saveSearchBaiscCollection.fullCollection.comparator = function(model) {
return getModelName(model);
@@ -141,6 +158,9 @@ define([
this.saveSearchAdvanceCollection.fullCollection.comparator = function(model) {
return getModelName(model);
}
+ this.saveSearchRelationshipCollection.fullCollection.comparator = function(model) {
+ return getModelName(model);
+ }
function getModelName(model) {
if (model.get('name')) {
@@ -190,6 +210,7 @@ define([
success: function(collection, data) {
that.saveSearchBaiscCollection.fullCollection.reset(_.where(data, { searchType: "BASIC" }));
that.saveSearchAdvanceCollection.fullCollection.reset(_.where(data, { searchType: "ADVANCED" }));
+ that.saveSearchRelationshipCollection.fullCollection.reset(_.where(data, { searchType: "BASIC_RELATIONSHIP" }));
that.changeLoaderState(false);
that.ui.refreshTree.attr("disabled", false);
},
@@ -300,9 +321,11 @@ define([
var that = this,
customFilterBasicList = [],
customFilterAdvanceList = [],
+ customFilterRelationshipList = [],
allCustomFilter = [],
customFilterBasicTreeData = that.saveSearchBaiscCollection.fullCollection.models,
customFilterAdvanceTreeData = that.saveSearchAdvanceCollection.fullCollection.models,
+ customFilterRelationshipTreeData = that.saveSearchRelationshipCollection.fullCollection.models,
openClassificationNodesState = function(treeDate) {
if (treeDate.length == 1) {
_.each(treeDate, function(model) {
@@ -311,13 +334,21 @@ define([
}
},
generateNode = function(nodeOptions) {
- var searchType = nodeOptions.get('searchType');
+ var searchType = nodeOptions.get('searchType'),
+ icon;
+ if(searchType === 'BASIC'){
+ icon = "fa fa-circle-thin basic-tree";
+ } else if (searchType === "BASIC_RELATIONSHIP"){
+ icon = "fa fa-circle-thin relationship-tree";
+ } else {
+ icon = "fa fa-circle-thin advance-tree";
+ }
var nodeStructure = {
text: _.escape(nodeOptions.get('name')),
name: _.escape(nodeOptions.get('name')),
type: "customFilter",
id: nodeOptions.get('guid'),
- icon: (searchType === 'BASIC' ? "fa fa-circle-thin basic-tree" : "fa fa-circle-thin advance-tree"),
+ icon: icon,
gType: "CustomFilter",
model: nodeOptions
}
@@ -333,6 +364,10 @@ define([
customFilterAdvanceList.push(generateNode(filterNode));
allCustomFilter.push(generateNode(filterNode));
});
+ _.each(customFilterRelationshipTreeData, function(filterNode) {
+ customFilterRelationshipList.push(generateNode(filterNode));
+ allCustomFilter.push(generateNode(filterNode));
+ });
var treeView = [{
icon: "fa fa-folder-o",
@@ -350,6 +385,14 @@ define([
text: "Advanced Search",
name: "Advanced Search",
state: { opened: true }
+ }, {
+ icon: "fa fa-folder-o",
+ gType: "customFilter",
+ type: "customFilterFolder",
+ children: customFilterRelationshipList,
+ text: "Relationship Search",
+ name: "Relationship Search",
+ state: { opened: true }
}];
var customFilterList = that.isGroupView ? treeView : allCustomFilter;
return customFilterList;
@@ -366,9 +409,17 @@ define([
params = CommonViewFunction.generateUrlFromSaveSearchObject({
value: { "searchParameters": searchParameters },
classificationDefCollection: that.classificationDefCollection,
- entityDefCollection: that.entityDefCollection
+ entityDefCollection: that.entityDefCollection,
+ relationshipDefCollection: that.relationshipDefCollection
});
- searchType === 'ADVANCED' ? that.isBasic = false : that.isBasic = true;
+ if (searchType === 'ADVANCED') {
+ that.isBasic = false
+ } else if (searchType === 'BASIC_RELATIONSHIP') {
+ that.isRelationship = true;
+ } else {
+ that.isBasic = true;
+ }
+
if (searchType === 'ADVANCED') {
Globals.advanceSearchData.searchByQuery = searchParameters.query;
Globals.advanceSearchData.searchByType = searchParameters.typeName;
@@ -377,14 +428,25 @@ define([
// Utils.notifyInfo({
// content: "Saved values are selected."
// })
-
- Utils.setUrl({
- url: '#!/search/searchResult',
- urlParams: _.extend({}, { 'searchType': that.isBasic ? 'basic' : 'dsl', 'isCF': true }, params),
- mergeBrowserUrl: false,
- trigger: true,
- updateTabState: true
- });
+ if (searchType === "BASIC" || searchType === "ADVANCED") {
+ Globals.fromRelationshipSearch = false;
+ Utils.setUrl({
+ url: '#!/search/searchResult',
+ urlParams: _.extend({}, { 'searchType': that.isBasic ? 'basic' : 'dsl', 'isCF': true }, params),
+ mergeBrowserUrl: false,
+ trigger: true,
+ updateTabState: true
+ });
+ } else {
+ Globals.fromRelationshipSearch = true;
+ Utils.setUrl({
+ url: '#!/relationship/relationshipSearchResult',
+ urlParams: _.extend({}, params, { 'searchType': 'basic', 'isCF': true }),
+ mergeBrowserUrl: false,
+ trigger: true,
+ updateTabState: true
+ });
+ }
}
} else {
@@ -420,7 +482,11 @@ define([
require([
'views/search/save/SaveModalLayoutView'
], function(SaveModalLayoutView) {
- new SaveModalLayoutView({ 'rename': true, 'selectedModel': options.model.clone(), 'collection': that.isBasic ? that.saveSearchBaiscCollection.fullCollection : that.saveSearchAdvanceCollection.fullCollection, 'getValue': that.getValue, 'isBasic': that.isBasic });
+ if(options.model.attributes.searchType === "BASIC" || options.model.attributes.searchType === "ADVANCED"){
+ new SaveModalLayoutView({ 'rename': true, 'selectedModel': options.model.clone(), 'collection': that.isBasic ? that.saveSearchBaiscCollection.fullCollection : that.saveSearchAdvanceCollection.fullCollection, 'getValue': that.getValue, 'isBasic': that.isBasic });
+ } else {
+ new SaveModalLayoutView({ 'rename': true, 'selectedModel': options.model.clone(), 'collection': that.saveSearchRelationshipCollection.fullCollection, 'getValue': that.getValue, 'isRelationship': that.isRelationship });
+ }
});
}
},
@@ -495,6 +561,24 @@ define([
})
}
},
+ relationshipSaveAs: function(e) {
+ var value = this.getValue();
+ if (value && value.relationshipName) {
+ this.isRelationship = true;
+ var urlObj = Utils.getUrlState.getQueryParams();
+ this.callSaveModalLayoutView({
+ 'collection': this.saveSearchRelationshipCollection.fullCollection,
+ getValue: function() {
+ return _.extend({}, value, urlObj);
+ },
+ 'isRelationship': this.isRelationship
+ });
+ } else {
+ Utils.notifyInfo({
+ content: Messages.search.favoriteSearch.notSelectedSearchFilter
+ })
+ }
+ },
refreshCustomFilterTree: function() {
this.fetchCustomFilter();
}
diff --git a/dashboardv3/public/js/views/search/tree/RelationshipSearchTreeLayoutView.js b/dashboardv3/public/js/views/search/tree/RelationshipSearchTreeLayoutView.js
new file mode 100644
index 000000000..e688d31f6
--- /dev/null
+++ b/dashboardv3/public/js/views/search/tree/RelationshipSearchTreeLayoutView.js
@@ -0,0 +1,300 @@
+/**
+ * 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",
+ "hbs!tmpl/search/tree/RelationshipLayoutView_tmpl",
+ "utils/Utils",
+ "utils/Globals",
+ "utils/UrlLinks",
+ "utils/CommonViewFunction",
+ 'utils/Enums',
+ "jstree"
+], function(require, RelationshipLayoutViewTmpl, Utils, Globals, UrlLinks, CommonViewFunction, Enums) {
+ "use strict";
+
+ var RelationshipSearchTreeLayoutView = Marionette.LayoutView.extend({
+ template: RelationshipLayoutViewTmpl,
+
+ regions: {},
+ ui: {
+ refreshTree: '[data-id="refreshTree"]',
+ relationshipSearchTree: '[data-id="relationshipSearchTree"]',
+ relationshipTreeLoader: '[data-id="relationshipTreeLoader"]'
+ },
+ templateHelpers: function() {
+ return {};
+ },
+ events: function() {
+ var events = {},
+ that = this;
+ events["click " + this.ui.refreshTree] = function(e) {
+ that.changeLoaderState(true);
+ that.ui.refreshTree.attr("disabled", true).tooltip("hide");
+ e.stopPropagation();
+ that.refresh();
+ };
+ return events;
+ },
+ bindEvents: function() {
+ var that = this;
+ this.listenTo(this.relationshipDefCollection, 'reset', function() {
+ that.relationshipTreeRefresh();
+ that.changeLoaderState(false);
+ that.ui.refreshTree.attr("disabled", false);
+ });
+ },
+ initialize: function(options) {
+ this.options = options;
+ _.extend(
+ this,
+ _.pick(
+ options,
+ "typeHeaders",
+ "searchVent",
+ "entityDefCollection",
+ "enumDefCollection",
+ "relationshipDefCollection",
+ "searchTableColumns",
+ "searchTableFilters",
+ "metricCollection"
+ )
+ );
+ this.relationshipId = null;
+ this.bindEvents();
+ },
+ onRender: function() {
+ this.changeLoaderState(true);
+ this.renderRelationshipTree();
+ this.changeLoaderState(false);
+ },
+ changeLoaderState: function(showLoader) {
+ if (showLoader) {
+ this.ui.relationshipSearchTree.hide();
+ this.ui.relationshipTreeLoader.show();
+ } else {
+ this.ui.relationshipSearchTree.show();
+ this.ui.relationshipTreeLoader.hide();
+ }
+ },
+ fetchCollection: function(e) {
+ this.relationshipDefCollection.fetch({ reset: true });
+ },
+ relationshipTreeRefresh: function() {
+ if (this.ui.relationshipSearchTree.jstree(true)) {
+ this.ui.relationshipSearchTree.jstree(true).refresh();
+ } else {
+ this.renderRelationshipTree();
+ }
+ },
+ renderRelationshipTree: function() {
+ var that = this;
+ this.generateSearchTree({
+ $el: that.ui.relationshipSearchTree
+ });
+ },
+ manualRender: function(options) {
+ var that = this;
+ _.extend(this.options, options);
+ if (this.options.value === undefined) {
+ this.options.value = {};
+ }
+ if (!this.options.value.relationshipName) {
+ this.ui.relationshipSearchTree.jstree(true).deselect_all();
+ this.relationshipId = null;
+ } else {
+ if (that.options.value.relationshipName) {
+ this.fromManualRender = true;
+ if (this.relationshipId) {
+ this.ui.relationshipSearchTree.jstree(true).deselect_node(this.relationshipId);
+ }
+ //this.relationshipId = Globals[that.options.value.relationshipName].guid;
+ this.ui.relationshipSearchTree.jstree(true).select_node(this.relationshipId);
+ } else if (that.options.value.relationshipName !== this.relationshipId) {
+ var dataFound = this.relationshipDefCollection.fullCollection.find(function(obj) {
+ return obj.get("name") === that.options.value.relationshipName;
+ });
+ if (dataFound) {
+ if ((this.relationshipId && this.relationshipId !== dataFound.get("guid")) || this.relationshipId === null) {
+ if (this.relationshipId) {
+ this.ui.relationshipSearchTree.jstree(true).deselect_node(this.relationshipId);
+ }
+ this.fromManualRender = true;
+ this.relationshipId = dataFound.get("guid");
+ this.ui.relationshipSearchTree.jstree(true).select_node(dataFound.get("guid"));
+ }
+ }
+ }
+ }
+ },
+ refresh: function() {
+ this.relationshipId = null;
+ this.fetchCollection({ reset: true });
+ },
+ onNodeSelect: function(options) {
+ var that = this,
+ type,
+ name = options.node.original.name,
+ selectedNodeId = options.node.id,
+ getUrl = Utils.getUrlState.isRelationTab(),
+ params = {
+ searchType: "basic",
+ dslChecked: false
+ },
+ values = this.options.value;
+ Globals.fromRelationshipSearch = true;
+ if (!getUrl) { that.relationshipId = null; }
+ if (that.relationshipId != selectedNodeId) {
+ that.relationshipId = selectedNodeId;
+ params["relationshipName"] = name;
+ } else {
+ that.relationshipId = params["relationshipName"] = null;
+ that.ui.relationshipSearchTree.jstree(true).deselect_all(true);
+ if (!that.options.value.relationshipName) {
+ that.showDefaultPage();
+ return;
+ }
+ }
+ if(values && (values.type || values.tag)){
+ values.attributes = null;
+ values.uiParameters = null;
+ }
+ var searchParam = _.extend({}, values, params);
+ this.triggerSearch(searchParam);
+ },
+ triggerSearch: function(params, url) {
+ var searchUrl = url ? url : '#!/relationship/relationshipSearchResult';
+ Utils.setUrl({
+ url: searchUrl,
+ urlParams: params,
+ mergeBrowserUrl: false,
+ trigger: true,
+ updateTabState: true
+ });
+ },
+ getRelationshipTree: function(options) {
+ var that = this,
+ collection = (options && options.collection) || this.relationshipDefCollection.fullCollection,
+ listofNodes = [],
+ relationshipName = that.options && that.options.value ? that.options.value.relationshipName : "",
+ generateNode = function(nodeOptions, options) {
+ var nodeStructure = {
+ text: _.escape(nodeOptions.name),
+ name: _.escape(nodeOptions.name),
+ id: nodeOptions.model.get("guid"),
+ icon: "fa fa-link",
+ gType: "Relationship",
+ state: {
+ disabled: false,
+ selected: (nodeOptions.name === relationshipName) ? true : false,
+ opened: true
+ }
+ }
+ return nodeStructure;
+ }
+ collection.each(function(model) {
+ var nodeDetails = {
+ name: _.escape(model.get('name')),
+ model: model
+ },
+ getParentNodeDetails = generateNode(nodeDetails, model);
+ listofNodes.push(getParentNodeDetails);
+ });
+ return listofNodes;
+ },
+ generateSearchTree: function(options) {
+ var $el = options && options.$el,
+ type = options && options.type,
+ that = this,
+ getEntityTreeConfig = function(opt) {
+ return {
+ plugins: ["search", "core", "sort", "conditionalselect", "changed", "wholerow", "node_customize"],
+ conditionalselect: function(node) {
+ var type = node.original.type;
+ if (type === "RELATIONSHIP") {
+ if (node.children.length) {
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return true;
+ }
+ },
+ state: { opened: true },
+ search: {
+ show_only_matches: true,
+ case_sensitive: false
+ },
+ node_customize: {
+ default: function(el, node) {
+ if (node.parent === "#") {
+ $(el).append('<div class="tools"><i class="fa"></i></div>');
+ } else {
+ $(el).append('<div class="tools"><i class="fa fa-ellipsis-h businessMetadataPopover" rel="popover"></i></div>');
+ }
+ }
+ },
+ core: {
+ multiple: false,
+ data: function(node, cb) {
+ if (node.id === "#") {
+ cb(that.getRelationshipTree());
+ }
+ }
+ }
+ };
+ };
+
+ $el.jstree(
+ getEntityTreeConfig({
+ type: ""
+ })
+ ).on("open_node.jstree", function(e, data) {
+ that.isTreeOpen = true;
+ }).on("select_node.jstree", function(e, data) {
+ if (that.fromManualRender !== true) {
+ that.onNodeSelect(data);
+ } else {
+ that.fromManualRender = false;
+ }
+ }).on("search.jstree", function(nodes, str, res) {
+ if (str.nodes.length === 0) {
+ $el.jstree(true).hide_all();
+ $el.parents(".panel").addClass("hide");
+ } else {
+ $el.parents(".panel").removeClass("hide");
+ }
+ }).on("hover_node.jstree", function(nodes, str, res) {
+ var aTag = that.$("#" + str.node.a_attr.id),
+ tagOffset = aTag.find(">.jstree-icon").offset();
+ that.$(".tree-tooltip").removeClass("show");
+ setTimeout(function() {
+ if (aTag.hasClass("jstree-hovered") && tagOffset.top && tagOffset.left) {
+ aTag.find(">span.tree-tooltip").css({
+ top: "calc(" + tagOffset.top + "px - 45px)",
+ left: "24px"
+ }).addClass("show");
+ }
+ }, 1200);
+ }).on("dehover_node.jstree", function(nodes, str, res) {
+ that.$(".tree-tooltip").removeClass("show");
+ });
+ }
+ });
+ return RelationshipSearchTreeLayoutView;
+});
\ No newline at end of file