You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by sa...@apache.org on 2019/06/17 20:28:46 UTC
[atlas] branch master updated: ATLAS-3282 : UI : use search
suggestions API for quick-search
This is an automated email from the ASF dual-hosted git repository.
sarath 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 9062e2c ATLAS-3282 : UI : use search suggestions API for quick-search
9062e2c is described below
commit 9062e2c861628d227f0c2616c5c84f2f90af9214
Author: kevalbhatt <kb...@apache.org>
AuthorDate: Mon Jun 17 18:27:22 2019 +0530
ATLAS-3282 : UI : use search suggestions API for quick-search
Signed-off-by: Sarath Subramanian <sa...@apache.org>
---
dashboardv2/public/css/bootstrap-sidebar.css | 2 +-
dashboardv2/public/css/scss/common.scss | 2 +-
dashboardv2/public/css/scss/theme.scss | 81 +++++----
dashboardv2/public/js/templates/site/Header.html | 61 ++++---
dashboardv2/public/js/utils/CommonViewFunction.js | 2 +-
dashboardv2/public/js/utils/Helper.js | 26 ++-
dashboardv2/public/js/views/graph/LineageUtils.js | 2 +-
dashboardv2/public/js/views/site/Header.js | 200 +++++++++++++++-------
8 files changed, 242 insertions(+), 134 deletions(-)
diff --git a/dashboardv2/public/css/bootstrap-sidebar.css b/dashboardv2/public/css/bootstrap-sidebar.css
index f0c1feb..23db223 100644
--- a/dashboardv2/public/css/bootstrap-sidebar.css
+++ b/dashboardv2/public/css/bootstrap-sidebar.css
@@ -59,7 +59,7 @@
.sidebar-nav>li {
line-height: 50px;
- padding: 0 20px;
+ padding: 5px 20px;
border-bottom: 1px #1c1e2a solid;
}
diff --git a/dashboardv2/public/css/scss/common.scss b/dashboardv2/public/css/scss/common.scss
index 484879b..75da4a4 100644
--- a/dashboardv2/public/css/scss/common.scss
+++ b/dashboardv2/public/css/scss/common.scss
@@ -86,7 +86,7 @@
.detail-page {
.details-backbutton {
- display: block !important;
+ display: table-cell !important;
}
}
diff --git a/dashboardv2/public/css/scss/theme.scss b/dashboardv2/public/css/scss/theme.scss
index 579d7fd..7d75136 100644
--- a/dashboardv2/public/css/scss/theme.scss
+++ b/dashboardv2/public/css/scss/theme.scss
@@ -25,50 +25,36 @@ body {
overflow-x: hidden;
}
-.detail-page {
- header.atlas-header {
- .nav.navbar-nav {
- width: 16%;
-
- @media screen and (max-width: 1024px) {
- width: 24%;
- }
- }
-
- .global-search-container {
- width: 65%;
-
- @media screen and (max-width: 1024px) {
- width: 45%;
- }
- }
- }
-}
-
header.atlas-header {
background-color: $white;
border-bottom: 1px $color_mystic_approx solid;
- .nav.navbar-nav {
- width: 5%;
- }
+ .navbar-nav {
+ display: table;
- .global-search-container {
- top: 8px;
- width: 76%;
+ li {
+ float: none;
+ display: table-cell;
+ padding: 0px 5px;
- @media screen and (max-width: 1024px) {
- width: 65%;
}
}
- .header-menu {
- width: 18%;
+ &>table {
+ td {
+ padding: 3px 2px;
+ position: relative;
+ transition: width 0.3s !important;
- @media screen and (max-width: 1024px) {
- width: 30%;
+ .global-search-container {
+ width: input {
+ width: 100%;
+ }
+ }
}
+ }
+ .header-menu {
.dropdown-menu>li>a {
color: $color_ironside_gray_approx;
@@ -81,7 +67,7 @@ header.atlas-header {
}
}
- >a {
+ td>a {
display: inline-block;
color: $color_ironside_gray_approx;
padding: 15px 14px;
@@ -149,7 +135,7 @@ header.atlas-header {
.page-title {
background-color: $color_white_lilac_approx;
- padding: 10px 15px 0px 15px;
+ padding: 15px 15px 0px 15px;
.title {
padding-top: 0;
@@ -480,6 +466,25 @@ hr[size="10"] {
.ui-menu.ui-widget-content.ui-autocomplete {
box-shadow: 0px 11px 30px -8px grey;
max-width: 60% !important;
+ max-height: 70vh;
+ overflow-y: auto;
+ /* prevent horizontal scrollbar */
+ overflow-x: hidden;
+
+ .ui-autocomplete-category {
+ padding: 10px;
+ color: #acacac;
+ text-transform: capitalize;
+ }
+
+ li.empty {
+ padding: 5px 2px;
+ line-height: 45px;
+
+ span.empty-message {
+ padding: 10px;
+ }
+ }
.ui-menu-item {
padding: 5px 2px;
@@ -496,17 +501,9 @@ hr[size="10"] {
.ui-state-active {
margin: 0px;
-
- &.empty {
- background: transparent;
- color: inherit !important;
- cursor: default;
- }
-
border: none;
background: #cee0fa;
color: $black !important;
- //color: #686868 !important;
}
a,
diff --git a/dashboardv2/public/js/templates/site/Header.html b/dashboardv2/public/js/templates/site/Header.html
index 4584205..d7b731d 100644
--- a/dashboardv2/public/js/templates/site/Header.html
+++ b/dashboardv2/public/js/templates/site/Header.html
@@ -15,27 +15,42 @@
* limitations under the License.
-->
<header class="clearfix atlas-header">
- <ul class="nav navbar-nav">
- <li>
- <a href="javascript:void(0);" data-id="menuHamburger"><i class="fa fa-bars"></i></a>
- </li>
- <li class="details-backbutton"><a href="javascript:void(0);" data-id="backButton"><i class="fa fa-chevron-left"></i> Back To Results</a></li>
- </ul>
- <div class="form-group has-feedback align-left-right-icon search-box pull-left global-search-container">
- <span class="fa fa-search form-control-feedback"></span>
- <input type="text" class="form-control global-search" name="global search" placeholder="Search entities" data-id="globalSearch" />
- <span class="fa fa-times form-control-feedback clearable" data-id="clearGlobalSearch"></span>
- </div>
- <div class="btn-group pull-right header-menu">
- <a class="show-stat" href="javascript:void(0);" title="Statistics"><i class="fa fa-bar-chart"></i></a>
- <a target="_blank" href="http://atlas.apache.org/"><i class="fa fa-question-circle"></i></a>
- <a href="javascript:void(0);" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="user-dropdown"><i class="fa fa-user user-circle "></i><span class="userName"></span></a>
- <ul class="dropdown-menu">
- <li class="aboutAtlas"><a href="javascript:void(0)">About</a></li>
- <li role="separator" class="divider"></li>
- <li>
- <a href="logout.html"><i class="fa fa-sign-out"></i>Logout</a>
- </li>
- </ul>
- </div>
+ <table>
+ <tr>
+ <td>
+ <ul class="nav navbar-nav">
+ <li>
+ <a href="javascript:void(0);" data-id="menuHamburger"><i class="fa fa-bars"></i></a>
+ </li>
+ <li class="details-backbutton"><a href="javascript:void(0);" data-id="backButton"><i class="fa fa-chevron-left"></i> Back To Results</a></li>
+ </ul>
+ </td>
+ <td class="global-search-container">
+ <div class="has-feedback align-left-right-icon search-box">
+ <span class="fa fa-search form-control-feedback"></span>
+ <input type="text" class="form-control global-search" name="global search" placeholder="Search entities" data-id="globalSearch" />
+ <span class="fa fa-times form-control-feedback clearable" data-id="clearGlobalSearch"></span>
+ </div>
+ </td>
+ <td>
+ <!-- <div class="btn-group pull-right header-menu"> -->
+ <table class="header-menu">
+ <tr>
+ <td><a class="show-stat" href="javascript:void(0);" title="Statistics"><i class="fa fa-bar-chart"></i></a></td>
+ <td><a target="_blank" href="http://atlas.apache.org/"><i class="fa fa-question-circle"></i></a></td>
+ <td>
+ <a href="javascript:void(0);" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="user-dropdown"><i class="fa fa-user user-circle "></i><span class="userName"></span></a>
+ <ul class="dropdown-menu">
+ <li class="aboutAtlas"><a href="javascript:void(0)">About</a></li>
+ <li role="separator" class="divider"></li>
+ <li>
+ <a href="logout.html"><i class="fa fa-sign-out"></i>Logout</a>
+ </li>
+ </ul>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
</header>
\ No newline at end of file
diff --git a/dashboardv2/public/js/utils/CommonViewFunction.js b/dashboardv2/public/js/utils/CommonViewFunction.js
index 1fc2402..11b05d8 100644
--- a/dashboardv2/public/js/utils/CommonViewFunction.js
+++ b/dashboardv2/public/js/utils/CommonViewFunction.js
@@ -688,7 +688,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
collection = options.collection,
isGlossaryView = options.isGlossaryView,
data = ref.ui[(isGlossaryView ? "glossaryForm" : "categoryTermForm")].serializeArray().reduce(function(obj, item) {
- obj[item.name] = item.value;
+ obj[item.name] = item.value.trim();
return obj;
}, {}),
newModel = new options.collection.model(),
diff --git a/dashboardv2/public/js/utils/Helper.js b/dashboardv2/public/js/utils/Helper.js
index 9886b9b..2b0f1e8 100644
--- a/dashboardv2/public/js/utils/Helper.js
+++ b/dashboardv2/public/js/utils/Helper.js
@@ -18,7 +18,8 @@
define(['require',
'utils/Utils',
'd3',
- 'marionette'
+ 'marionette',
+ 'jquery-ui'
], function(require, Utils, d3) {
'use strict';
_.mixin({
@@ -201,6 +202,29 @@ define(['require',
return adapter;
});
+ $.widget("custom.atlasAutoComplete", $.ui.autocomplete, {
+ _create: function() {
+ this._super();
+ this.widget().menu("option", "items", "> :not(.ui-autocomplete-category,.empty)");
+ },
+ _renderMenu: function(ul, items) {
+ var that = this,
+ currentCategory = "";
+ items = _.sortBy(items, 'order');
+ $.each(items, function(index, item) {
+ var li;
+ if (item.category != currentCategory) {
+ ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>");
+ currentCategory = item.category;
+ }
+ that._renderItemData(ul, item);
+ });
+ },
+ _renderItemData: function(ul, item) {
+ return this._renderItem(ul, item);
+ }
+ });
+
// For placeholder support
if (!('placeholder' in HTMLInputElement.prototype)) {
var originalRender = Backbone.Marionette.LayoutView.prototype.render;
diff --git a/dashboardv2/public/js/views/graph/LineageUtils.js b/dashboardv2/public/js/views/graph/LineageUtils.js
index 2f50fbd..d2da39a 100644
--- a/dashboardv2/public/js/views/graph/LineageUtils.js
+++ b/dashboardv2/public/js/views/graph/LineageUtils.js
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-define(['require', ''], function(require) {
+define(['require'], function(require) {
'use strict';
var LinegaeUtils = {};
LinegaeUtils.DragNode = function(options) {
diff --git a/dashboardv2/public/js/views/site/Header.js b/dashboardv2/public/js/views/site/Header.js
index 30c0420..f4543b1 100644
--- a/dashboardv2/public/js/views/site/Header.js
+++ b/dashboardv2/public/js/views/site/Header.js
@@ -61,13 +61,35 @@ define(['require',
this.ui.clearGlobalSearch.removeClass("in");
};
events['click ' + this.ui.menuHamburger] = function() {
+ this.setSearchBoxWidth({
+ updateWidth: function(atlasHeaderWidth) {
+ return $('body').hasClass('full-screen') ? atlasHeaderWidth - 350 : atlasHeaderWidth + 350
+ }
+ });
$('body').toggleClass("full-screen");
};
return events;
},
- initialize: function(options) {},
-
+ initialize: function(options) {
+ this.bindEvent();
+ },
+ setSearchBoxWidth: function(options) {
+ var atlasHeaderWidth = this.$el.find(".atlas-header").width(),
+ minusWidth = Utils.getUrlState.isDetailPage() ? 400 : 250;
+ if (options && options.updateWidth) {
+ atlasHeaderWidth = options.updateWidth(atlasHeaderWidth);
+ }
+ if (atlasHeaderWidth > minusWidth) {
+ this.$el.find(".global-search-container").width(atlasHeaderWidth - minusWidth);
+ }
+ },
+ bindEvent: function() {
+ var that = this;
+ $(window).resize(function() {
+ that.setSearchBoxWidth()
+ });
+ },
onRender: function() {
var that = this;
if (Globals.userLogedIn.status) {
@@ -75,23 +97,53 @@ define(['require',
}
this.initializeGlobalSearch();
},
- getSearchUrlQueryParam: function(request) {
- var term = request.term;
- return {
- "excludeDeletedEntities": true,
- "includeSubClassifications": true,
- "includeSubTypes": true,
- "includeClassificationAttributes": true,
- "entityFilters": null,
- "tagFilters": null,
- "attributes": null,
- "query": this.getSearchString(term),
- "limit": 5,
- "offset": 0,
- "typeName": null,
- "classification": null,
- "termName": null
- }
+ onShow: function() {
+ this.setSearchBoxWidth();
+ },
+ onBeforeDestroy: function() {
+ this.ui.globalSearch.atlasAutoComplete("destroy");
+ },
+ fetchSearchData: function(options) {
+ var that = this,
+ request = options.request,
+ response = options.response,
+ term = request.term,
+ sendResponse = function() {
+ var query = that.cache[term].query,
+ suggestions = that.cache[term].suggestions;
+ if (query !== undefined && suggestions !== undefined) {
+ response(that.cache[term]);
+ }
+ };
+ $.ajax({
+ url: UrlLinks.searchApiUrl('quick'),
+ contentType: 'application/json',
+ data: {
+ "query": this.getSearchString(term),
+ "limit": 5,
+ "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 } });
+ sendResponse();
+ }
+ });
+
+ $.ajax({
+ url: UrlLinks.searchApiUrl('suggestions'),
+ contentType: 'application/json',
+ data: {
+ "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);
+ }
+ });
},
getSearchString: function(str) {
if (str && str.length) {
@@ -103,86 +155,106 @@ define(['require',
initializeGlobalSearch: function() {
var that = this;
this.cache = {};
- this.ui.globalSearch.autocomplete({
+ this.ui.globalSearch.atlasAutoComplete({
minLength: 1,
autoFocus: false,
search: function() {
$(this).siblings('span.fa-search').removeClass("fa-search").addClass("fa-refresh fa-spin-custom");
},
focus: function(event, ui) {
- //$(this).val(ui.item.itemText);
return false;
},
open: function() {
$(this).siblings('span.fa-refresh').removeClass("fa-refresh fa-spin-custom").addClass("fa-search");
},
select: function(event, ui) {
- if (ui && ui.item && ui.item.value == "Empty") {
- return false
- } else {
+ var item = ui && ui.item;
+ event.preventDefault();
+ event.stopPropagation();
+ if (_.isString(item)) {
+ var $el = $(this);
+ $el.val(item);
+ $el.data("valSelected", true);
+ setTimeout(function() {
+ $el.atlasAutoComplete("search");
+ }, 10);
+ } else if (_.isObject(item) && item.guid) {
Utils.setUrl({
- url: '#!/detailPage/' + ui.item.guid,
+ url: '#!/detailPage/' + item.guid,
mergeBrowserUrl: false,
trigger: true
});
- return true
}
+ return true;
},
source: function(request, response) {
var term = request.term;
- if (term in that.cache) {
+ if (that.cache && that.cache[term]) {
response(that.cache[term]);
return;
}
-
- $.ajax({
- type: 'POST',
- url: UrlLinks.searchApiUrl('basic'),
- contentType: 'application/json',
- data: JSON.stringify(that.getSearchUrlQueryParam(request)),
- cache: true,
- success: function(data) {
- var data = data.entities;
- if (data === undefined) {
- data = ["Empty"];
- }
- that.cache[term] = data;
- response(data);
- }
+ that.fetchSearchData({
+ request: request,
+ response: response
});
}
}).focus(function() {
- $(this).autocomplete("search");
+ $(this).atlasAutoComplete("search");
}).keyup(function(event) {
if ($(this).val().trim() === "") {
that.ui.clearGlobalSearch.removeClass("in");
} else {
that.ui.clearGlobalSearch.addClass("in");
if (event.keyCode == 13) {
- Utils.setUrl({
- url: '#!/search/searchResult?query=' + encodeURIComponent(that.getSearchString($(this).val())) + '&searchType=basic',
- mergeBrowserUrl: false,
- trigger: true
- });
+ if ($(this).data("valSelected") !== true) {
+ Utils.setUrl({
+ url: '#!/search/searchResult?query=' + encodeURIComponent(that.getSearchString($(this).val())) + '&searchType=basic',
+ mergeBrowserUrl: false,
+ trigger: true
+ });
+ } else {
+ $(this).data("valSelected", false);
+ }
}
}
- }).autocomplete("instance")._renderItem = function(ul, item) {
- if (item && item.value == "Empty") {
- return $("<li>")
- .append("<span class='empty'>No record found</span>")
- .appendTo(ul);
+ }).atlasAutoComplete("instance")._renderItem = function(ul, searchItem) {
+ if (searchItem) {
+ var data = searchItem.data;
+ if (data) {
+ if (data.length == 0) {
+ return $("<li class='empty'></li>")
+ .append("<span class='empty-message'>No " + searchItem.category + " found</span>")
+ .appendTo(ul);
+ } else {
+ var items = [];
+ _.each(data, function(item) {
+ var li = null;
+ if (_.isObject(item)) {
+ item.itemText = Utils.getName(item) + " (" + item.typeName + ")";
+ var options = {},
+ table = '';
+ options.entityData = item;
+ 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>")
+ .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);
+ }
+ if (searchItem.category) {
+ items.push(li.attr("aria-label", searchItem.category + " : " + (_.isObject(item) ? item.itemText : item)));
+ }
+ });
+ return ul.append(items);
+ }
+ }
}
- item.itemText = Utils.getName(item) + " (" + item.typeName + ")";
- var options = {},
- table = '';
- options.entityData = item;
- var img = $('<img src="' + Utils.getEntityIconPath(options) + '">').on('error', function(error, s) {
- this.src = Utils.getEntityIconPath(_.extend(options, { errorUrl: this.src }));
- });
- var link = $("<a class='search-entity-anchor ellipsis' href='#!/detailPage/" + item.guid + "'>" + item.itemText + "</a>").prepend(img);
- return $("<li class='with-icon'>")
- .append(link)
- .appendTo(ul);
};
}
});