You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by kb...@apache.org on 2019/06/25 05:37:12 UTC
[atlas] branch master updated: ATLAS-3294 : UI: Quick-search UI
visual appearance enhancement
This is an automated email from the ASF dual-hosted git repository.
kbhatt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git
The following commit(s) were added to refs/heads/master by this push:
new 66390fe ATLAS-3294 : UI: Quick-search UI visual appearance enhancement
66390fe is described below
commit 66390fe8467b1c199d3769800703fb99f676cf22
Author: kevalbhatt <kb...@apache.org>
AuthorDate: Mon Jun 24 17:50:06 2019 +0530
ATLAS-3294 : UI: Quick-search UI visual appearance enhancement
---
dashboardv2/public/css/scss/common.scss | 10 ++
dashboardv2/public/css/scss/theme.scss | 13 +-
dashboardv2/public/js/router/Router.js | 175 +++++++++++++--------
dashboardv2/public/js/utils/CommonViewFunction.js | 30 +++-
dashboardv2/public/js/utils/Utils.js | 4 +-
.../js/views/entity/EntityDetailTableLayoutView.js | 12 +-
.../public/js/views/graph/LineageLayoutView.js | 5 +-
dashboardv2/public/js/views/site/Header.js | 75 +++++----
8 files changed, 207 insertions(+), 117 deletions(-)
diff --git a/dashboardv2/public/css/scss/common.scss b/dashboardv2/public/css/scss/common.scss
index 75da4a4..17e892a 100644
--- a/dashboardv2/public/css/scss/common.scss
+++ b/dashboardv2/public/css/scss/common.scss
@@ -88,6 +88,16 @@
.details-backbutton {
display: table-cell !important;
}
+
+ .searched-term-highlight {
+ background-color: #eeee31;
+ transition: background-color 4s, font-weight 2s;
+
+ &.bold {
+ background-color: transparent;
+ font-weight: bold;
+ }
+ }
}
pre {
diff --git a/dashboardv2/public/css/scss/theme.scss b/dashboardv2/public/css/scss/theme.scss
index 7d75136..e220b5a 100644
--- a/dashboardv2/public/css/scss/theme.scss
+++ b/dashboardv2/public/css/scss/theme.scss
@@ -45,12 +45,6 @@ header.atlas-header {
padding: 3px 2px;
position: relative;
transition: width 0.3s !important;
-
- .global-search-container {
- width: input {
- width: 100%;
- }
- }
}
}
@@ -499,6 +493,13 @@ hr[size="10"] {
}
}
+ span.searched-term {
+ display: inline-block;
+ padding: 0;
+ font-weight: bold;
+ color: $black !important;
+ }
+
.ui-state-active {
margin: 0px;
border: none;
diff --git a/dashboardv2/public/js/router/Router.js b/dashboardv2/public/js/router/Router.js
index 759ac0f..99a5d92 100644
--- a/dashboardv2/public/js/router/Router.js
+++ b/dashboardv2/public/js/router/Router.js
@@ -89,6 +89,16 @@ define([
});
},
showRegions: function() {},
+ renderViewIfNotExists: function(options) {
+ var view = options.view,
+ render = options.render,
+ manualRender = options.manualRender;
+ if (!view.currentView) {
+ if (render) view.show(options.render());
+ } else {
+ if (manualRender) options.manualRender();
+ }
+ },
/**
* @override
@@ -110,6 +120,17 @@ define([
// console.log("Post-Route Change Operations can be performed here !!");
// console.log("Route changed: ", name);
},
+ getHeaderOptions: function(Header) {
+ return {
+ view: App.rNHeader,
+ manualRender: function() {
+ this.view.currentView.manualRender();
+ },
+ render: function() {
+ return new Header();
+ }
+ }
+ },
detailPage: function(id) {
var that = this;
if (id) {
@@ -121,14 +142,18 @@ define([
], function(Header, DetailPageLayoutView, SideNavLayoutView, VEntityList) {
this.entityCollection = new VEntityList([], {});
var paramObj = Utils.getUrlState.getQueryParams();
- App.rNHeader.show(new Header());
- if (!App.rSideNav.currentView) {
- App.rSideNav.show(new SideNavLayoutView(
- _.extend({}, that.preFetchedCollectionLists, that.sharedObj)
- ));
- } else {
- App.rSideNav.currentView.selectTab();
- }
+ that.renderViewIfNotExists(that.getHeaderOptions(Header));
+ that.renderViewIfNotExists({
+ view: App.rSideNav,
+ manualRender: function() {
+ this.view.currentView.selectTab();
+ },
+ render: function() {
+ return new SideNavLayoutView(
+ _.extend({}, that.preFetchedCollectionLists, that.sharedObj)
+ );
+ }
+ });
App.rNContent.show(new DetailPageLayoutView(_.extend({
'collection': this.entityCollection,
'id': id,
@@ -148,32 +173,36 @@ define([
], function(Header, SideNavLayoutView, TagDetailLayoutView) {
var paramObj = Utils.getUrlState.getQueryParams(),
url = Utils.getUrlState.getQueryUrl().queyParams[0];
- App.rNHeader.show(new Header());
- if (!App.rSideNav.currentView) {
- if (paramObj && paramObj.dlttag) {
- Utils.setUrl({
- url: url,
- trigger: false,
- updateTabState: true
- });
- }
- App.rSideNav.show(new SideNavLayoutView(
- _.extend({
- 'tag': tagName,
- 'value': paramObj
- }, that.preFetchedCollectionLists, that.sharedObj)
- ));
- } else {
- if (paramObj && paramObj.dlttag) {
- Utils.setUrl({
- url: url,
- trigger: false,
- updateTabState: true
- });
+ that.renderViewIfNotExists(that.getHeaderOptions(Header));
+ that.renderViewIfNotExists({
+ view: App.rSideNav,
+ manualRender: function() {
+ if (paramObj && paramObj.dlttag) {
+ Utils.setUrl({
+ url: url,
+ trigger: false,
+ updateTabState: true
+ });
+ }
+ this.view.currentView.RTagLayoutView.currentView.manualRender(_.extend({}, paramObj, { 'tagName': tagName }));
+ this.view.currentView.selectTab();
+ },
+ render: function() {
+ if (paramObj && paramObj.dlttag) {
+ Utils.setUrl({
+ url: url,
+ trigger: false,
+ updateTabState: true
+ });
+ }
+ return new SideNavLayoutView(
+ _.extend({
+ 'tag': tagName,
+ 'value': paramObj
+ }, that.preFetchedCollectionLists, that.sharedObj)
+ );
}
- App.rSideNav.currentView.RTagLayoutView.currentView.manualRender(_.extend({}, paramObj, { 'tagName': tagName }));
- App.rSideNav.currentView.selectTab();
- }
+ });
if (tagName) {
// updating paramObj to check for new queryparam.
paramObj = Utils.getUrlState.getQueryParams();
@@ -198,15 +227,19 @@ define([
'views/site/SideNavLayoutView'
], function(Header, GlossaryDetailLayoutView, SideNavLayoutView) {
var paramObj = Utils.getUrlState.getQueryParams();
- App.rNHeader.show(new Header());
- if (!App.rSideNav.currentView) {
- App.rSideNav.show(new SideNavLayoutView(
- _.extend({}, that.preFetchedCollectionLists, that.sharedObj, { 'guid': id, 'value': paramObj })
- ));
- } else {
- App.rSideNav.currentView.RGlossaryLayoutView.currentView.manualRender(_.extend({}, { 'guid': id, 'value': paramObj }));
- App.rSideNav.currentView.selectTab();
- }
+ that.renderViewIfNotExists(that.getHeaderOptions(Header));
+ that.renderViewIfNotExists({
+ view: App.rSideNav,
+ manualRender: function() {
+ this.view.currentView.RGlossaryLayoutView.currentView.manualRender(_.extend({}, { 'guid': id, 'value': paramObj }));
+ this.view.currentView.selectTab();
+ },
+ render: function() {
+ return new SideNavLayoutView(
+ _.extend({}, that.preFetchedCollectionLists, that.sharedObj, { 'guid': id, 'value': paramObj })
+ )
+ }
+ });
App.rNContent.show(new GlossaryDetailLayoutView(_.extend({
'guid': id,
'value': paramObj
@@ -222,21 +255,25 @@ define([
'views/search/SearchDetailLayoutView',
], function(Header, SideNavLayoutView, SearchDetailLayoutView) {
var paramObj = Utils.getUrlState.getQueryParams();
- App.rNHeader.show(new Header());
- if (!App.rSideNav.currentView) {
- App.rSideNav.show(new SideNavLayoutView(
- _.extend({
- 'searchVent': that.searchVent
- }, that.preFetchedCollectionLists, that.sharedObj)
- ));
- } else {
- App.rSideNav.currentView.selectTab();
- if (Utils.getUrlState.isTagTab()) {
- App.rSideNav.currentView.RTagLayoutView.currentView.manualRender();
- } else if (Utils.getUrlState.isGlossaryTab()) {
- App.rSideNav.currentView.RGlossaryLayoutView.currentView.manualRender(_.extend({ "isTrigger": true }, { "value": paramObj }));
+ that.renderViewIfNotExists(that.getHeaderOptions(Header));
+ that.renderViewIfNotExists({
+ view: App.rSideNav,
+ manualRender: function() {
+ this.view.currentView.selectTab();
+ if (Utils.getUrlState.isTagTab()) {
+ this.view.currentView.RTagLayoutView.currentView.manualRender();
+ } else if (Utils.getUrlState.isGlossaryTab()) {
+ this.view.currentView.RGlossaryLayoutView.currentView.manualRender(_.extend({ "isTrigger": true }, { "value": paramObj }));
+ }
+ },
+ render: function() {
+ return new SideNavLayoutView(
+ _.extend({
+ 'searchVent': that.searchVent
+ }, that.preFetchedCollectionLists, that.sharedObj)
+ )
}
- }
+ });
if (Globals.entityCreate && Utils.getUrlState.isSearchTab()) {
App.rNContent.show(new SearchDetailLayoutView(
@@ -263,17 +300,21 @@ define([
var isinitialView = true,
isTypeTagNotExists = false,
tempParam = _.extend({}, paramObj);
- App.rNHeader.show(new Header());
- if (!App.rSideNav.currentView) {
- App.rSideNav.show(new SideNavLayoutView(
- _.extend({
- 'value': paramObj,
- 'searchVent': that.searchVent
- }, that.preFetchedCollectionLists, that.sharedObj)
- ));
- } else {
- App.rSideNav.currentView.RSearchLayoutView.currentView.manualRender(paramObj);
- }
+ that.renderViewIfNotExists(that.getHeaderOptions(Header));
+ that.renderViewIfNotExists({
+ view: App.rSideNav,
+ manualRender: function() {
+ this.view.currentView.RSearchLayoutView.currentView.manualRender(paramObj);
+ },
+ render: function() {
+ return new SideNavLayoutView(
+ _.extend({
+ 'value': paramObj,
+ 'searchVent': that.searchVent
+ }, that.preFetchedCollectionLists, that.sharedObj)
+ )
+ }
+ });
App.rSideNav.currentView.selectTab();
if (paramObj) {
isinitialView = (paramObj.type || (paramObj.dslChecked == "true" ? "" : (paramObj.tag || paramObj.term)) || (paramObj.query ? paramObj.query.trim() : "")).length === 0;
diff --git a/dashboardv2/public/js/utils/CommonViewFunction.js b/dashboardv2/public/js/utils/CommonViewFunction.js
index 11b05d8..2754c1a 100644
--- a/dashboardv2/public/js/utils/CommonViewFunction.js
+++ b/dashboardv2/public/js/utils/CommonViewFunction.js
@@ -80,15 +80,29 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
attributeDefs = options.attributeDefs,
formatIntVal = options.formatIntVal,
showListCount = options.showListCount || true,
+ highlightString = options.highlightString,
numberFormat = options.numberFormat || _.numberFormatWithComa;
var table = "",
+ getHighlightedString = function(resultStr) {
+ if (highlightString && highlightString.length) {
+ try {
+ return resultStr.replace(new RegExp(highlightString, "gi"), function(foundStr) {
+ return "<span class='searched-term-highlight'>" + foundStr + "</span>"
+ });
+ } catch (error) {
+ return resultStr;
+ }
+ } else {
+ return resultStr;
+ }
+ },
getValue = function(val) {
if (val) {
if ((_.isNumber(val) || !_.isNaN(parseInt(val))) && formatIntVal) {
return numberFormat(val);
} else {
- return val;
+ return getHighlightedString(val);
}
} else {
return "N/A";
@@ -180,9 +194,9 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
}
}
});
- valueOfArray.push(Utils.JSONPrettyPrint(newAttributesList));
+ valueOfArray.push(Utils.JSONPrettyPrint(newAttributesList, getValue));
} else {
- valueOfArray.push(Utils.JSONPrettyPrint(attributesList));
+ valueOfArray.push(Utils.JSONPrettyPrint(attributesList, getValue));
}
}
if (id && inputOutputField) {
@@ -193,7 +207,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
fetchInputOutputValue(fetchId, defEntity);
tempLink += '<div data-id="' + fetchId + '"><div class="value-loader"></div></div>';
} else {
- tempLink += '<a href="#!/detailPage/' + id + '">' + name + '</a>'
+ tempLink += '<a href="#!/detailPage/' + id + '">' + getValue(name) + '</a>'
}
}
if (readOnly) {
@@ -247,14 +261,14 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
if (_.isObject(valueObject[key])) {
val = keyValue
} else if (Utils.isUrl(keyValue)) {
- val = '<a target="_blank" class="blue-link" href="' + keyValue + '">' + keyValue + '</a>';
+ val = '<a target="_blank" class="blue-link" href="' + keyValue + '">' + getValue(keyValue) + '</a>';
} else if (key === 'guid' || key === "__guid") {
- val = '<a title="' + key + '" href="#!/detailPage/' + keyValue + '">' + keyValue + '</a>';
+ val = '<a title="' + key + '" href="#!/detailPage/' + keyValue + '">' + getValue(keyValue) + '</a>';
} else {
- val = _.escape(keyValue);
+ val = getValue(_.escape(keyValue));
}
if (isTable) {
- var value = getValue(val),
+ var value = val,
appendClass = (value == "N/A" ? "hide-row" : ""),
htmlTag = '<div class="scroll-y">' + value + '</div>';
if (_.isObject(valueObject[key]) && !_.isEmpty(valueObject[key])) {
diff --git a/dashboardv2/public/js/utils/Utils.js b/dashboardv2/public/js/utils/Utils.js
index 94c08c8..5274ef3 100644
--- a/dashboardv2/public/js/utils/Utils.js
+++ b/dashboardv2/public/js/utils/Utils.js
@@ -816,7 +816,7 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
return regexp.test(url);
}
- Utils.JSONPrettyPrint = function(obj) {
+ Utils.JSONPrettyPrint = function(obj, getValue) {
var replacer = function(match, pIndent, pKey, pVal, pEnd) {
var key = '<span class=json-key>';
var val = '<span class=json-value>';
@@ -825,7 +825,7 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
if (pKey)
r = r + key + pKey.replace(/[": ]/g, '') + '</span>: ';
if (pVal)
- r = r + (pVal[0] == '"' ? str : val) + pVal + '</span>';
+ r = r + (pVal[0] == '"' ? str : val) + getValue(pVal) + '</span>';
return r + (pEnd || '');
},
jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/mg;
diff --git a/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js b/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js
index 1c8ff9b..381d99e 100644
--- a/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js
+++ b/dashboardv2/public/js/views/entity/EntityDetailTableLayoutView.js
@@ -64,12 +64,22 @@ define(['require',
this.entityTableGenerate();
},
entityTableGenerate: function() {
- var table = CommonViewFunction.propertyTable({ scope: this, valueObject: this.entity.attributes, attributeDefs: this.attributeDefs });
+ var that = this,
+ highlightString = $(".atlas-header .global-search-container input.global-search").val(),
+ table = CommonViewFunction.propertyTable({
+ scope: this,
+ valueObject: this.entity.attributes,
+ attributeDefs: this.attributeDefs,
+ highlightString: highlightString
+ });
this.ui.detailValue.append(table);
Utils.togglePropertyRelationshipTableEmptyValues({
"inputType": this.ui.noValueToggle,
"tableEl": this.ui.detailValue
});
+ setTimeout(function() {
+ that.$el.find(".searched-term-highlight").addClass("bold");
+ }, 5000)
}
});
return EntityDetailTableLayoutView;
diff --git a/dashboardv2/public/js/views/graph/LineageLayoutView.js b/dashboardv2/public/js/views/graph/LineageLayoutView.js
index 85293d7..bdc9ee2 100644
--- a/dashboardv2/public/js/views/graph/LineageLayoutView.js
+++ b/dashboardv2/public/js/views/graph/LineageLayoutView.js
@@ -228,6 +228,9 @@ define(['require',
skipDefaultError: true,
queryParam: queryParam,
success: function(data) {
+ if (that.isDestroyed) {
+ return;
+ }
if (data.relations.length) {
that.lineageData = $.extend(true, {}, data);
that.relationshipMap = that.crateLineageRelationshipHashMap(data);
@@ -864,7 +867,7 @@ define(['require',
typeStr += '<option value="' + obj.guid + '">' + obj.attributes.name + '</option>';
});
}
- that.ui.lineageTypeSearch.html(typeStr);
+ this.ui.lineageTypeSearch.html(typeStr);
this.initilizelineageTypeSearch();
},
initilizelineageTypeSearch: function() {
diff --git a/dashboardv2/public/js/views/site/Header.js b/dashboardv2/public/js/views/site/Header.js
index f4543b1..6ed42fb 100644
--- a/dashboardv2/public/js/views/site/Header.js
+++ b/dashboardv2/public/js/views/site/Header.js
@@ -76,7 +76,7 @@ define(['require',
},
setSearchBoxWidth: function(options) {
var atlasHeaderWidth = this.$el.find(".atlas-header").width(),
- minusWidth = Utils.getUrlState.isDetailPage() ? 400 : 250;
+ minusWidth = Utils.getUrlState.isDetailPage() ? 413 : 263;
if (options && options.updateWidth) {
atlasHeaderWidth = options.updateWidth(atlasHeaderWidth);
}
@@ -87,7 +87,7 @@ define(['require',
bindEvent: function() {
var that = this;
$(window).resize(function() {
- that.setSearchBoxWidth()
+ that.setSearchBoxWidth();
});
},
onRender: function() {
@@ -103,16 +103,20 @@ define(['require',
onBeforeDestroy: function() {
this.ui.globalSearch.atlasAutoComplete("destroy");
},
+ manualRender: function() {
+ this.setSearchBoxWidth();
+ },
fetchSearchData: function(options) {
var that = this,
request = options.request,
response = options.response,
term = request.term,
+ data = {},
sendResponse = function() {
- var query = that.cache[term].query,
- suggestions = that.cache[term].suggestions;
+ var query = data.query,
+ suggestions = data.suggestions;
if (query !== undefined && suggestions !== undefined) {
- response(that.cache[term]);
+ response(data);
}
};
$.ajax({
@@ -124,9 +128,9 @@ define(['require',
"offset": 0
},
cache: true,
- success: function(data) {
- var data = data.searchResults.entities || [];
- that.cache[term] = _.extend({}, that.cache[term], { query: { category: "entities", data: data, order: 1 } });
+ success: function(response) {
+ var rData = response.searchResults.entities || [];
+ data.query = { category: "entities", data: rData, order: 1 };
sendResponse();
}
});
@@ -138,10 +142,10 @@ define(['require',
"prefixString": term
},
cache: true,
- success: function(data) {
- var data = data.suggestions || [];
- that.cache[term] = _.extend({}, that.cache[term], { suggestions: { category: "suggestions", data: data, order: 2 } });
- sendResponse(data);
+ success: function(response) {
+ var rData = response.suggestions || [];
+ data.suggestions = { category: "suggestions", data: rData, order: 2 };
+ sendResponse();
}
});
},
@@ -152,9 +156,16 @@ define(['require',
return str;
}
},
+ triggerBuasicSearch: function(query) {
+ Utils.setUrl({
+ url: '#!/search/searchResult?query=' + encodeURIComponent(query) + '&searchType=basic',
+ mergeBrowserUrl: false,
+ trigger: true,
+ updateTabState: true
+ });
+ },
initializeGlobalSearch: function() {
var that = this;
- this.cache = {};
this.ui.globalSearch.atlasAutoComplete({
minLength: 1,
autoFocus: false,
@@ -171,13 +182,11 @@ define(['require',
var item = ui && ui.item;
event.preventDefault();
event.stopPropagation();
+ var $el = $(this);
if (_.isString(item)) {
- var $el = $(this);
$el.val(item);
$el.data("valSelected", true);
- setTimeout(function() {
- $el.atlasAutoComplete("search");
- }, 10);
+ that.triggerBuasicSearch(item);
} else if (_.isObject(item) && item.guid) {
Utils.setUrl({
url: '#!/detailPage/' + item.guid,
@@ -185,14 +194,10 @@ define(['require',
trigger: true
});
}
+ $el.blur();
return true;
},
source: function(request, response) {
- var term = request.term;
- if (that.cache && that.cache[term]) {
- response(that.cache[term]);
- return;
- }
that.fetchSearchData({
request: request,
response: response
@@ -207,19 +212,26 @@ define(['require',
that.ui.clearGlobalSearch.addClass("in");
if (event.keyCode == 13) {
if ($(this).data("valSelected") !== true) {
- Utils.setUrl({
- url: '#!/search/searchResult?query=' + encodeURIComponent(that.getSearchString($(this).val())) + '&searchType=basic',
- mergeBrowserUrl: false,
- trigger: true
- });
+ that.triggerBuasicSearch(that.getSearchString($(this).val()));
} else {
$(this).data("valSelected", false);
}
}
}
}).atlasAutoComplete("instance")._renderItem = function(ul, searchItem) {
+
if (searchItem) {
- var data = searchItem.data;
+ var data = searchItem.data,
+ searchTerm = this.term,
+ getHighlightedTerm = function(resultStr) {
+ try {
+ return resultStr.replace(new RegExp(searchTerm, "gi"), function(foundStr) {
+ return "<span class='searched-term'>" + foundStr + "</span>";
+ });
+ } catch (error) {
+ return resultStr;
+ }
+ }
if (data) {
if (data.length == 0) {
return $("<li class='empty'></li>")
@@ -237,16 +249,15 @@ define(['require',
var img = $('<img src="' + Utils.getEntityIconPath(options) + '">').on('error', function(error, s) {
this.src = Utils.getEntityIconPath(_.extend(options, { errorUrl: this.src }));
});
- var span = $("<span>" + item.itemText + "</span>")
+ var span = $("<span>" + (getHighlightedTerm(item.itemText)) + "</span>")
.prepend(img);
li = $("<li class='with-icon'>")
.append(span);
- li.data("ui-autocomplete-item", item);
} else {
li = $("<li>")
- .append("<span>" + item + "</span>")
- li.data("ui-autocomplete-item", item);
+ .append("<span>" + (getHighlightedTerm(item)) + "</span>");
}
+ li.data("ui-autocomplete-item", item);
if (searchItem.category) {
items.push(li.attr("aria-label", searchItem.category + " : " + (_.isObject(item) ? item.itemText : item)));
}