* 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.tags/v1.21.12.1
| @@ -1230,104 +1230,53 @@ function hideWhenLostFocus(body, parent) { | |||||
| } | } | ||||
| function searchUsers() { | function searchUsers() { | ||||
| if (!$('#search-user-box .results').length) { | |||||
| return; | |||||
| } | |||||
| var $searchUserBox = $('#search-user-box'); | 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 } | |||||
| } | } | ||||
| }); | |||||
| }); | |||||
| $searchUserBox.find('input').focus(function () { | |||||
| $searchUserBox.keyup(); | |||||
| }, | |||||
| searchFields: ['login', 'full_name'], | |||||
| showNoResults: false | |||||
| }); | }); | ||||
| hideWhenLostFocus('#search-user-box .results', '#search-user-box'); | |||||
| } | } | ||||
| // FIXME: merge common parts in two functions | |||||
| function searchRepositories() { | function searchRepositories() { | ||||
| if (!$('#search-repo-box .results').length) { | |||||
| return; | |||||
| } | |||||
| var $searchRepoBox = $('#search-repo-box'); | 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(''); | |||||
| $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 | |||||
| }) | |||||
| }); | |||||
| 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 } | |||||
| } | } | ||||
| }); | |||||
| }); | |||||
| $searchRepoBox.find('input').focus(function () { | |||||
| $searchRepoBox.keyup(); | |||||
| }, | |||||
| searchFields: ['full_name'], | |||||
| showNoResults: false | |||||
| }); | }); | ||||
| hideWhenLostFocus('#search-repo-box .results', '#search-repo-box'); | |||||
| } | } | ||||
| function initCodeView() { | function initCodeView() { | ||||
| @@ -1345,20 +1345,15 @@ | |||||
| #search-repo-box, | #search-repo-box, | ||||
| #search-user-box { | #search-user-box { | ||||
| .results { | .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; | margin-right: 8px; | ||||
| width: 2em; | |||||
| height: 2em; | |||||
| } | |||||
| .content { | |||||
| margin: 6px 0; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -8,11 +8,10 @@ | |||||
| <form class="ui form" action="{{.Link}}" method="post"> | <form class="ui form" action="{{.Link}}" method="post"> | ||||
| {{.CsrfTokenHtml}} | {{.CsrfTokenHtml}} | ||||
| <div class="inline field ui left"> | <div class="inline field ui left"> | ||||
| <div id="search-user-box"> | |||||
| <div id="search-user-box" class="ui search"> | |||||
| <div class="ui input"> | <div class="ui input"> | ||||
| <input class="prompt" name="uname" placeholder="{{.i18n.Tr "repo.settings.search_user_placeholder"}}" autocomplete="off" autofocus required> | <input class="prompt" name="uname" placeholder="{{.i18n.Tr "repo.settings.search_user_placeholder"}}" autocomplete="off" autofocus required> | ||||
| </div> | </div> | ||||
| <div class="ui segment results hide"></div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <button class="ui blue button">{{.i18n.Tr "org.members.invite_now"}}</button> | <button class="ui blue button">{{.i18n.Tr "org.members.invite_now"}}</button> | ||||
| @@ -28,11 +28,10 @@ | |||||
| {{.CsrfTokenHtml}} | {{.CsrfTokenHtml}} | ||||
| <input type="hidden" name="uid" value="{{.SignedUser.ID}}"> | <input type="hidden" name="uid" value="{{.SignedUser.ID}}"> | ||||
| <div class="inline field ui left"> | <div class="inline field ui left"> | ||||
| <div id="search-user-box"> | |||||
| <div id="search-user-box" class="ui search"> | |||||
| <div class="ui input"> | <div class="ui input"> | ||||
| <input class="prompt" name="uname" placeholder="{{.i18n.Tr "repo.settings.search_user_placeholder"}}" autocomplete="off" required> | <input class="prompt" name="uname" placeholder="{{.i18n.Tr "repo.settings.search_user_placeholder"}}" autocomplete="off" required> | ||||
| </div> | </div> | ||||
| <div class="ui segment results hide"></div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <button class="ui green button">{{.i18n.Tr "org.teams.add_team_member"}}</button> | <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"> | <form class="ui form" id="add-repo-form" action="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/repo/add" method="post"> | ||||
| {{.CsrfTokenHtml}} | {{.CsrfTokenHtml}} | ||||
| <div class="inline field ui left"> | <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"> | <div class="ui input"> | ||||
| <input class="prompt" name="repo_name" placeholder="{{.i18n.Tr "org.teams.search_repo_placeholder"}}" autocomplete="off" required> | <input class="prompt" name="repo_name" placeholder="{{.i18n.Tr "org.teams.search_repo_placeholder"}}" autocomplete="off" required> | ||||
| </div> | </div> | ||||
| <div class="ui segment results hide"></div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <button class="ui green button">{{.i18n.Tr "org.teams.add_team_repository"}}</button> | <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"> | <form class="ui form" id="repo-collab-form" action="{{.Link}}" method="post"> | ||||
| {{.CsrfTokenHtml}} | {{.CsrfTokenHtml}} | ||||
| <div class="inline field ui left"> | <div class="inline field ui left"> | ||||
| <div id="search-user-box"> | |||||
| <div id="search-user-box" class="ui search"> | |||||
| <div class="ui input"> | <div class="ui input"> | ||||
| <input class="prompt" name="collaborator" placeholder="{{.i18n.Tr "repo.settings.search_user_placeholder"}}" autocomplete="off" autofocus required> | <input class="prompt" name="collaborator" placeholder="{{.i18n.Tr "repo.settings.search_user_placeholder"}}" autocomplete="off" autofocus required> | ||||
| </div> | </div> | ||||
| <div class="ui segment results hide"></div> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <button class="ui green button">{{.i18n.Tr "repo.settings.add_collaborator"}}</button> | <button class="ui green button">{{.i18n.Tr "repo.settings.add_collaborator"}}</button> | ||||