Use Semantic UI's Search component for user and repo search (#2636)

* Use search component on org invitation user input.

* Search component for collaboration and members.

* Search component for repo search.

* minCharacters for search input

* Display full_name for user search.

* Fixed missing uid query parameter for repo search.

* Removed unused comment.
This commit is contained in:
harry 2017-10-02 22:27:48 -05:00 committed by Lauris BH
parent a04718a2a6
commit b3cfa5a77e
7 changed files with 49 additions and 109 deletions

File diff suppressed because one or more lines are too long

View file

@ -1230,104 +1230,53 @@ function hideWhenLostFocus(body, parent) {
}
function searchUsers() {
if (!$('#search-user-box .results').length) {
return;
}
var $searchUserBox = $('#search-user-box');
var $results = $searchUserBox.find('.results');
$searchUserBox.keyup(function () {
var $this = $(this);
var keyword = $this.find('input').val();
if (keyword.length < 2) {
$results.hide();
return;
}
$searchUserBox.search({
minCharacters: 2,
apiSettings: {
url: suburl + '/api/v1/users/search?q={query}',
onResponse: function(response) {
var items = [];
$.each(response.data, function (i, item) {
var title = item.login;
if (item.full_name && item.full_name.length > 0) {
title += ' (' + item.full_name + ')';
}
items.push({
title: title,
image: item.avatar_url
})
});
$.ajax({
url: suburl + '/api/v1/users/search?q=' + keyword,
dataType: "json",
success: function (response) {
var notEmpty = function (str) {
return str && str.length > 0;
};
$results.html('');
if (response.ok && response.data.length) {
var html = '';
$.each(response.data, function (i, item) {
html += '<div class="item"><img class="ui avatar image" src="' + item.avatar_url + '"><span class="username">' + item.login + '</span>';
if (notEmpty(item.full_name)) {
html += ' (' + item.full_name + ')';
}
html += '</div>';
});
$results.html(html);
$this.find('.results .item').click(function () {
$this.find('input').val($(this).find('.username').text());
$results.hide();
});
$results.show();
} else {
$results.hide();
}
return { results: items }
}
});
},
searchFields: ['login', 'full_name'],
showNoResults: false
});
$searchUserBox.find('input').focus(function () {
$searchUserBox.keyup();
});
hideWhenLostFocus('#search-user-box .results', '#search-user-box');
}
// FIXME: merge common parts in two functions
function searchRepositories() {
if (!$('#search-repo-box .results').length) {
return;
}
var $searchRepoBox = $('#search-repo-box');
var $results = $searchRepoBox.find('.results');
$searchRepoBox.keyup(function () {
var $this = $(this);
var keyword = $this.find('input').val();
if (keyword.length < 2) {
$results.hide();
return;
}
$searchRepoBox.search({
minCharacters: 2,
apiSettings: {
url: suburl + '/api/v1/repos/search?q={query}&uid=' + $searchRepoBox.data('uid'),
onResponse: function(response) {
var items = [];
$.each(response.data, function (i, item) {
items.push({
title: item.full_name.split("/")[1],
description: item.full_name
})
});
$.ajax({
url: suburl + '/api/v1/repos/search?q=' + keyword + "&uid=" + $searchRepoBox.data('uid'),
dataType: "json",
success: function (response) {
var notEmpty = function (str) {
return str && str.length > 0;
};
$results.html('');
if (response.ok && response.data.length) {
var html = '';
$.each(response.data, function (i, item) {
html += '<div class="item"><i class="icon octicon octicon-repo"></i> <span class="fullname">' + item.full_name + '</span></div>';
});
$results.html(html);
$this.find('.results .item').click(function () {
$this.find('input').val($(this).find('.fullname').text().split("/")[1]);
$results.hide();
});
$results.show();
} else {
$results.hide();
}
return { results: items }
}
});
},
searchFields: ['full_name'],
showNoResults: false
});
$searchRepoBox.find('input').focus(function () {
$searchRepoBox.keyup();
});
hideWhenLostFocus('#search-repo-box .results', '#search-repo-box');
}
function initCodeView() {

View file

@ -1345,20 +1345,15 @@
#search-repo-box,
#search-user-box {
.results {
padding: 0;
position: absolute;
.item {
padding: 10px 15px;
border-bottom: 1px solid #DDD;
cursor: pointer;
&:hover {
background: rgba(0,0,0,.05)!important;
color: rgba(0,0,0,.95)!important;
}
img {
.result {
.image {
float: left;
margin-right: 8px;
width: 2em;
height: 2em;
}
.content {
margin: 6px 0;
}
}
}

View file

@ -8,11 +8,10 @@
<form class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<div class="inline field ui left">
<div id="search-user-box">
<div id="search-user-box" class="ui search">
<div class="ui input">
<input class="prompt" name="uname" placeholder="{{.i18n.Tr "repo.settings.search_user_placeholder"}}" autocomplete="off" autofocus required>
</div>
<div class="ui segment results hide"></div>
</div>
</div>
<button class="ui blue button">{{.i18n.Tr "org.members.invite_now"}}</button>

View file

@ -28,11 +28,10 @@
{{.CsrfTokenHtml}}
<input type="hidden" name="uid" value="{{.SignedUser.ID}}">
<div class="inline field ui left">
<div id="search-user-box">
<div id="search-user-box" class="ui search">
<div class="ui input">
<input class="prompt" name="uname" placeholder="{{.i18n.Tr "repo.settings.search_user_placeholder"}}" autocomplete="off" required>
</div>
<div class="ui segment results hide"></div>
</div>
</div>
<button class="ui green button">{{.i18n.Tr "org.teams.add_team_member"}}</button>

View file

@ -28,11 +28,10 @@
<form class="ui form" id="add-repo-form" action="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/repo/add" method="post">
{{.CsrfTokenHtml}}
<div class="inline field ui left">
<div id="search-repo-box" data-uid="{{.Org.ID}}">
<div id="search-repo-box" data-uid="{{.Org.ID}}" class="ui search">
<div class="ui input">
<input class="prompt" name="repo_name" placeholder="{{.i18n.Tr "org.teams.search_repo_placeholder"}}" autocomplete="off" required>
</div>
<div class="ui segment results hide"></div>
</div>
</div>
<button class="ui green button">{{.i18n.Tr "org.teams.add_team_repository"}}</button>

View file

@ -42,11 +42,10 @@
<form class="ui form" id="repo-collab-form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<div class="inline field ui left">
<div id="search-user-box">
<div id="search-user-box" class="ui search">
<div class="ui input">
<input class="prompt" name="collaborator" placeholder="{{.i18n.Tr "repo.settings.search_user_placeholder"}}" autocomplete="off" autofocus required>
</div>
<div class="ui segment results hide"></div>
</div>
</div>
<button class="ui green button">{{.i18n.Tr "repo.settings.add_collaborator"}}</button>