Commit 9062e2c8 by kevalbhatt Committed by Sarath Subramanian

ATLAS-3282 : UI : use search suggestions API for quick-search

parent 4e1eeb4c
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
.sidebar-nav>li { .sidebar-nav>li {
line-height: 50px; line-height: 50px;
padding: 0 20px; padding: 5px 20px;
border-bottom: 1px #1c1e2a solid; border-bottom: 1px #1c1e2a solid;
} }
......
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
.detail-page { .detail-page {
.details-backbutton { .details-backbutton {
display: block !important; display: table-cell !important;
} }
} }
......
...@@ -25,50 +25,36 @@ body { ...@@ -25,50 +25,36 @@ body {
overflow-x: hidden; 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 { header.atlas-header {
background-color: $white; background-color: $white;
border-bottom: 1px $color_mystic_approx solid; border-bottom: 1px $color_mystic_approx solid;
.nav.navbar-nav { .navbar-nav {
width: 5%; display: table;
}
.global-search-container { li {
top: 8px; float: none;
width: 76%; display: table-cell;
padding: 0px 5px;
@media screen and (max-width: 1024px) {
width: 65%;
} }
} }
.header-menu { &>table {
width: 18%; td {
padding: 3px 2px;
position: relative;
transition: width 0.3s !important;
@media screen and (max-width: 1024px) { .global-search-container {
width: 30%; width: input {
width: 100%;
}
}
}
} }
.header-menu {
.dropdown-menu>li>a { .dropdown-menu>li>a {
color: $color_ironside_gray_approx; color: $color_ironside_gray_approx;
...@@ -81,7 +67,7 @@ header.atlas-header { ...@@ -81,7 +67,7 @@ header.atlas-header {
} }
} }
>a { td>a {
display: inline-block; display: inline-block;
color: $color_ironside_gray_approx; color: $color_ironside_gray_approx;
padding: 15px 14px; padding: 15px 14px;
...@@ -149,7 +135,7 @@ header.atlas-header { ...@@ -149,7 +135,7 @@ header.atlas-header {
.page-title { .page-title {
background-color: $color_white_lilac_approx; background-color: $color_white_lilac_approx;
padding: 10px 15px 0px 15px; padding: 15px 15px 0px 15px;
.title { .title {
padding-top: 0; padding-top: 0;
...@@ -480,6 +466,25 @@ hr[size="10"] { ...@@ -480,6 +466,25 @@ hr[size="10"] {
.ui-menu.ui-widget-content.ui-autocomplete { .ui-menu.ui-widget-content.ui-autocomplete {
box-shadow: 0px 11px 30px -8px grey; box-shadow: 0px 11px 30px -8px grey;
max-width: 60% !important; 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 { .ui-menu-item {
padding: 5px 2px; padding: 5px 2px;
...@@ -496,17 +501,9 @@ hr[size="10"] { ...@@ -496,17 +501,9 @@ hr[size="10"] {
.ui-state-active { .ui-state-active {
margin: 0px; margin: 0px;
&.empty {
background: transparent;
color: inherit !important;
cursor: default;
}
border: none; border: none;
background: #cee0fa; background: #cee0fa;
color: $black !important; color: $black !important;
//color: #686868 !important;
} }
a, a,
......
...@@ -15,20 +15,30 @@ ...@@ -15,20 +15,30 @@
* limitations under the License. * limitations under the License.
--> -->
<header class="clearfix atlas-header"> <header class="clearfix atlas-header">
<table>
<tr>
<td>
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li> <li>
<a href="javascript:void(0);" data-id="menuHamburger"><i class="fa fa-bars"></i></a> <a href="javascript:void(0);" data-id="menuHamburger"><i class="fa fa-bars"></i></a>
</li> </li>
<li class="details-backbutton"><a href="javascript:void(0);" data-id="backButton"><i class="fa fa-chevron-left"></i> Back To Results</a></li> <li class="details-backbutton"><a href="javascript:void(0);" data-id="backButton"><i class="fa fa-chevron-left"></i> Back To Results</a></li>
</ul> </ul>
<div class="form-group has-feedback align-left-right-icon search-box pull-left global-search-container"> </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> <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" /> <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> <span class="fa fa-times form-control-feedback clearable" data-id="clearGlobalSearch"></span>
</div> </div>
<div class="btn-group pull-right header-menu"> </td>
<a class="show-stat" href="javascript:void(0);" title="Statistics"><i class="fa fa-bar-chart"></i></a> <td>
<a target="_blank" href="http://atlas.apache.org/"><i class="fa fa-question-circle"></i></a> <!-- <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> <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"> <ul class="dropdown-menu">
<li class="aboutAtlas"><a href="javascript:void(0)">About</a></li> <li class="aboutAtlas"><a href="javascript:void(0)">About</a></li>
...@@ -37,5 +47,10 @@ ...@@ -37,5 +47,10 @@
<a href="logout.html"><i class="fa fa-sign-out"></i>Logout</a> <a href="logout.html"><i class="fa fa-sign-out"></i>Logout</a>
</li> </li>
</ul> </ul>
</div> </td>
</tr>
</table>
</td>
</tr>
</table>
</header> </header>
\ No newline at end of file
...@@ -688,7 +688,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum ...@@ -688,7 +688,7 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
collection = options.collection, collection = options.collection,
isGlossaryView = options.isGlossaryView, isGlossaryView = options.isGlossaryView,
data = ref.ui[(isGlossaryView ? "glossaryForm" : "categoryTermForm")].serializeArray().reduce(function(obj, item) { data = ref.ui[(isGlossaryView ? "glossaryForm" : "categoryTermForm")].serializeArray().reduce(function(obj, item) {
obj[item.name] = item.value; obj[item.name] = item.value.trim();
return obj; return obj;
}, {}), }, {}),
newModel = new options.collection.model(), newModel = new options.collection.model(),
......
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
define(['require', define(['require',
'utils/Utils', 'utils/Utils',
'd3', 'd3',
'marionette' 'marionette',
'jquery-ui'
], function(require, Utils, d3) { ], function(require, Utils, d3) {
'use strict'; 'use strict';
_.mixin({ _.mixin({
...@@ -201,6 +202,29 @@ define(['require', ...@@ -201,6 +202,29 @@ define(['require',
return adapter; 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 // For placeholder support
if (!('placeholder' in HTMLInputElement.prototype)) { if (!('placeholder' in HTMLInputElement.prototype)) {
var originalRender = Backbone.Marionette.LayoutView.prototype.render; var originalRender = Backbone.Marionette.LayoutView.prototype.render;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* limitations under the License. * limitations under the License.
*/ */
define(['require', ''], function(require) { define(['require'], function(require) {
'use strict'; 'use strict';
var LinegaeUtils = {}; var LinegaeUtils = {};
LinegaeUtils.DragNode = function(options) { LinegaeUtils.DragNode = function(options) {
......
...@@ -61,13 +61,35 @@ define(['require', ...@@ -61,13 +61,35 @@ define(['require',
this.ui.clearGlobalSearch.removeClass("in"); this.ui.clearGlobalSearch.removeClass("in");
}; };
events['click ' + this.ui.menuHamburger] = function() { events['click ' + this.ui.menuHamburger] = function() {
this.setSearchBoxWidth({
updateWidth: function(atlasHeaderWidth) {
return $('body').hasClass('full-screen') ? atlasHeaderWidth - 350 : atlasHeaderWidth + 350
}
});
$('body').toggleClass("full-screen"); $('body').toggleClass("full-screen");
}; };
return events; 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() { onRender: function() {
var that = this; var that = this;
if (Globals.userLogedIn.status) { if (Globals.userLogedIn.status) {
...@@ -75,23 +97,53 @@ define(['require', ...@@ -75,23 +97,53 @@ define(['require',
} }
this.initializeGlobalSearch(); this.initializeGlobalSearch();
}, },
getSearchUrlQueryParam: function(request) { onShow: function() {
var term = request.term; this.setSearchBoxWidth();
return { },
"excludeDeletedEntities": true, onBeforeDestroy: function() {
"includeSubClassifications": true, this.ui.globalSearch.atlasAutoComplete("destroy");
"includeSubTypes": true, },
"includeClassificationAttributes": true, fetchSearchData: function(options) {
"entityFilters": null, var that = this,
"tagFilters": null, request = options.request,
"attributes": null, 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), "query": this.getSearchString(term),
"limit": 5, "limit": 5,
"offset": 0, "offset": 0
"typeName": null, },
"classification": null, cache: true,
"termName": null 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) { getSearchString: function(str) {
if (str && str.length) { if (str && str.length) {
...@@ -103,75 +155,81 @@ define(['require', ...@@ -103,75 +155,81 @@ define(['require',
initializeGlobalSearch: function() { initializeGlobalSearch: function() {
var that = this; var that = this;
this.cache = {}; this.cache = {};
this.ui.globalSearch.autocomplete({ this.ui.globalSearch.atlasAutoComplete({
minLength: 1, minLength: 1,
autoFocus: false, autoFocus: false,
search: function() { search: function() {
$(this).siblings('span.fa-search').removeClass("fa-search").addClass("fa-refresh fa-spin-custom"); $(this).siblings('span.fa-search').removeClass("fa-search").addClass("fa-refresh fa-spin-custom");
}, },
focus: function(event, ui) { focus: function(event, ui) {
//$(this).val(ui.item.itemText);
return false; return false;
}, },
open: function() { open: function() {
$(this).siblings('span.fa-refresh').removeClass("fa-refresh fa-spin-custom").addClass("fa-search"); $(this).siblings('span.fa-refresh').removeClass("fa-refresh fa-spin-custom").addClass("fa-search");
}, },
select: function(event, ui) { select: function(event, ui) {
if (ui && ui.item && ui.item.value == "Empty") { var item = ui && ui.item;
return false event.preventDefault();
} else { 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({ Utils.setUrl({
url: '#!/detailPage/' + ui.item.guid, url: '#!/detailPage/' + item.guid,
mergeBrowserUrl: false, mergeBrowserUrl: false,
trigger: true trigger: true
}); });
return true
} }
return true;
}, },
source: function(request, response) { source: function(request, response) {
var term = request.term; var term = request.term;
if (term in that.cache) { if (that.cache && that.cache[term]) {
response(that.cache[term]); response(that.cache[term]);
return; return;
} }
that.fetchSearchData({
$.ajax({ request: request,
type: 'POST', response: response
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);
}
}); });
} }
}).focus(function() { }).focus(function() {
$(this).autocomplete("search"); $(this).atlasAutoComplete("search");
}).keyup(function(event) { }).keyup(function(event) {
if ($(this).val().trim() === "") { if ($(this).val().trim() === "") {
that.ui.clearGlobalSearch.removeClass("in"); that.ui.clearGlobalSearch.removeClass("in");
} else { } else {
that.ui.clearGlobalSearch.addClass("in"); that.ui.clearGlobalSearch.addClass("in");
if (event.keyCode == 13) { if (event.keyCode == 13) {
if ($(this).data("valSelected") !== true) {
Utils.setUrl({ Utils.setUrl({
url: '#!/search/searchResult?query=' + encodeURIComponent(that.getSearchString($(this).val())) + '&searchType=basic', url: '#!/search/searchResult?query=' + encodeURIComponent(that.getSearchString($(this).val())) + '&searchType=basic',
mergeBrowserUrl: false, mergeBrowserUrl: false,
trigger: true 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 + ")"; item.itemText = Utils.getName(item) + " (" + item.typeName + ")";
var options = {}, var options = {},
table = ''; table = '';
...@@ -179,10 +237,24 @@ define(['require', ...@@ -179,10 +237,24 @@ define(['require',
var img = $('<img src="' + Utils.getEntityIconPath(options) + '">').on('error', function(error, s) { var img = $('<img src="' + Utils.getEntityIconPath(options) + '">').on('error', function(error, s) {
this.src = Utils.getEntityIconPath(_.extend(options, { errorUrl: this.src })); 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); var span = $("<span>" + item.itemText + "</span>")
return $("<li class='with-icon'>") .prepend(img);
.append(link) li = $("<li class='with-icon'>")
.appendTo(ul); .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);
}
}
}
}; };
} }
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment