mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-26 01:40:36 +00:00
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:
parent
a04718a2a6
commit
b3cfa5a77e
7 changed files with 49 additions and 109 deletions
File diff suppressed because one or more lines are too long
|
@ -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;
|
||||
}
|
||||
|
||||
$.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 = '';
|
||||
$searchUserBox.search({
|
||||
minCharacters: 2,
|
||||
apiSettings: {
|
||||
url: suburl + '/api/v1/users/search?q={query}',
|
||||
onResponse: function(response) {
|
||||
var items = [];
|
||||
$.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 + ')';
|
||||
var title = item.login;
|
||||
if (item.full_name && item.full_name.length > 0) {
|
||||
title += ' (' + item.full_name + ')';
|
||||
}
|
||||
html += '</div>';
|
||||
items.push({
|
||||
title: title,
|
||||
image: item.avatar_url
|
||||
})
|
||||
});
|
||||
$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;
|
||||
}
|
||||
|
||||
$.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 = '';
|
||||
$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) {
|
||||
html += '<div class="item"><i class="icon octicon octicon-repo"></i> <span class="fullname">' + item.full_name + '</span></div>';
|
||||
items.push({
|
||||
title: item.full_name.split("/")[1],
|
||||
description: item.full_name
|
||||
})
|
||||
});
|
||||
$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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue