Implement new search UI

We now have both autocomplete-based searching for quick results, as well as a full search page for a full listing of results
This commit is contained in:
Joseph Schorr 2017-04-07 17:25:44 -04:00
parent 8b148bf1d4
commit e9ffe0e27b
23 changed files with 649 additions and 393 deletions

View file

@ -28,18 +28,6 @@ angular.module('quay').directive('headerBar', function () {
hotkeysAdded = true;
// Register hotkeys.
if ($scope.searchingAllowed) {
hotkeys.add({
combo: '/',
description: 'Show search',
callback: function(e) {
e.preventDefault();
e.stopPropagation();
$scope.toggleSearch();
}
});
}
if (!cUser.anonymous) {
hotkeys.add({
combo: 'alt+c',
@ -57,9 +45,6 @@ angular.module('quay').directive('headerBar', function () {
$scope.Features = Features;
$scope.notificationService = NotificationService;
$scope.searchingAllowed = false;
$scope.searchVisible = false;
$scope.currentSearchQuery = null;
$scope.searchResultState = null;
$scope.showBuildDialogCounter = 0;
// Monitor any user changes and place the current user into the scope.
@ -79,69 +64,6 @@ angular.module('quay').directive('headerBar', function () {
$scope.currentPageContext['repository'] = r;
});
var documentSearchMaxResults = 10;
var documentSearchScoreThreshold = 0.9;
var conductDocumentationSearch = function(query) {
if (!query) { return; }
var mapper = function(result, score) {
return {
'kind': 'doc',
'name': result.title.replace(/&#39\;/g, "'"),
'score': score,
'href': Config.DOCUMENTATION_LOCATION + result.url
}
};
DocumentationService.findDocumentation($scope, query.split(' '), function(results) {
if (!$scope.searchVisible) { return; }
var currentResults = $scope.searchResultState['results'] || [];
results.forEach(function(result) {
if (currentResults.length < documentSearchMaxResults) {
currentResults.push(result);
}
});
$scope.searchResultState = {
'state': currentResults.length ? 'results' : 'no-results',
'results': currentResults,
'current': currentResults.length ? 0 : -1
};
}, mapper, documentSearchScoreThreshold);
}
var conductSearch = function(query) {
if (!query) { $scope.searchResultState = null; return; }
$scope.searchResultState = {
'state': 'loading'
};
var params = {
'query': query
};
ApiService.conductSearch(null, params).then(function(resp) {
if (!$scope.searchVisible || query != $scope.currentSearchQuery) { return; }
$scope.searchResultState = {
'state': resp.results.length ? 'results' : 'no-results',
'results': resp.results,
'current': resp.results.length ? 0 : -1
};
if (resp.results.length < documentSearchMaxResults) {
conductDocumentationSearch(query);
}
}, function(resp) {
$scope.searchResultState = null;
}, /* background */ true);
};
$scope.$watch('currentSearchQuery', conductSearch);
$scope.signout = function() {
ApiService.logout().then(function() {
UserService.load();
@ -153,75 +75,6 @@ angular.module('quay').directive('headerBar', function () {
return Config.getEnterpriseLogo();
};
$scope.toggleSearch = function() {
$scope.searchVisible = !$scope.searchVisible;
if ($scope.searchVisible) {
$('#search-box-input').focus();
if ($scope.currentSearchQuery) {
conductSearch($scope.currentSearchQuery);
}
} else {
$('#search-box-input').blur()
$scope.searchResultState = null;
}
};
$scope.getSearchBoxClasses = function(searchVisible, searchResultState) {
var classes = searchVisible ? 'search-visible ' : '';
if (searchResultState) {
classes += 'results-visible';
}
return classes;
};
$scope.handleSearchKeyDown = function(e) {
if (e.keyCode == 27) {
$scope.toggleSearch();
return;
}
var state = $scope.searchResultState;
if (!state || !state['results']) { return; }
if (e.keyCode == 40) {
state['current']++;
e.preventDefault();
} else if (e.keyCode == 38) {
state['current']--;
e.preventDefault();
} else if (e.keyCode == 13) {
var current = state['current'];
if (current >= 0 && current < state['results'].length) {
$scope.showResult(state['results'][current]);
}
e.preventDefault();
}
if (state['current'] < -1) {
state['current'] = state['results'].length - 1;
} else if (state['current'] >= state['results'].length) {
state['current'] = 0;
}
};
$scope.showResult = function(result) {
$scope.toggleSearch();
$timeout(function() {
if (result['kind'] == 'doc') {
window.location = result['href'];
return;
}
$scope.currentSearchQuery = '';
$location.url(result['href'])
}, 500);
};
$scope.setCurrentResult = function(result) {
if (!$scope.searchResultState) { return; }
$scope.searchResultState['current'] = result;
};
$scope.getNamespace = function(context) {
if (!context) { return null; }