Commit f0f88390c1309b0d5a8cead701477e21c2174f05
1 parent
1d48904a
Exists in
spb-stable
and in
3 other branches
project_user selectbox with ajax autocomplete
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Showing
7 changed files
with
98 additions
and
13 deletions
Show diff stats
app/assets/javascripts/api.js.coffee
@@ -3,6 +3,7 @@ | @@ -3,6 +3,7 @@ | ||
3 | user_path: "/api/:version/users/:id.json" | 3 | user_path: "/api/:version/users/:id.json" |
4 | notes_path: "/api/:version/projects/:id/notes.json" | 4 | notes_path: "/api/:version/projects/:id/notes.json" |
5 | namespaces_path: "/api/:version/namespaces.json" | 5 | namespaces_path: "/api/:version/namespaces.json" |
6 | + project_users_path: "/api/:version/projects/:id/users.json" | ||
6 | 7 | ||
7 | # Get 20 (depends on api) recent notes | 8 | # Get 20 (depends on api) recent notes |
8 | # and sort the ascending from oldest to newest | 9 | # and sort the ascending from oldest to newest |
@@ -50,6 +51,23 @@ | @@ -50,6 +51,23 @@ | ||
50 | ).done (users) -> | 51 | ).done (users) -> |
51 | callback(users) | 52 | callback(users) |
52 | 53 | ||
54 | + # Return project users list. Filtered by query | ||
55 | + # Only active users retrieved | ||
56 | + projectUsers: (project_id, query, callback) -> | ||
57 | + url = Api.buildUrl(Api.project_users_path) | ||
58 | + url = url.replace(':id', project_id) | ||
59 | + | ||
60 | + $.ajax( | ||
61 | + url: url | ||
62 | + data: | ||
63 | + private_token: gon.api_token | ||
64 | + search: query | ||
65 | + per_page: 20 | ||
66 | + active: true | ||
67 | + dataType: "json" | ||
68 | + ).done (users) -> | ||
69 | + callback(users) | ||
70 | + | ||
53 | # Return namespaces list. Filtered by query | 71 | # Return namespaces list. Filtered by query |
54 | namespaces: (query, callback) -> | 72 | namespaces: (query, callback) -> |
55 | url = Api.buildUrl(Api.namespaces_path) | 73 | url = Api.buildUrl(Api.namespaces_path) |
@@ -0,0 +1,43 @@ | @@ -0,0 +1,43 @@ | ||
1 | +$ -> | ||
2 | + projectUserFormatResult = (user) -> | ||
3 | + if user.avatar_url | ||
4 | + avatar = user.avatar_url | ||
5 | + else if gon.gravatar_enabled | ||
6 | + avatar = gon.gravatar_url | ||
7 | + avatar = avatar.replace('%{hash}', md5(user.email)) | ||
8 | + avatar = avatar.replace('%{size}', '24') | ||
9 | + else | ||
10 | + avatar = gon.relative_url_root + "/assets/no_avatar.png" | ||
11 | + | ||
12 | + "<div class='user-result'> | ||
13 | + <div class='user-image'><img class='avatar s24' src='#{avatar}'></div> | ||
14 | + <div class='user-name'>#{user.name}</div> | ||
15 | + <div class='user-username'>#{user.username}</div> | ||
16 | + </div>" | ||
17 | + | ||
18 | + projectUserFormatSelection = (user) -> | ||
19 | + user.name | ||
20 | + | ||
21 | + $('.ajax-project-users-select').each (i, select) -> | ||
22 | + project_id = $('body').data('project-id') | ||
23 | + $(select).select2 | ||
24 | + placeholder: "Search for a user" | ||
25 | + multiple: $(select).hasClass('multiselect') | ||
26 | + minimumInputLength: 0 | ||
27 | + query: (query) -> | ||
28 | + Api.projectUsers project_id, query.term, (users) -> | ||
29 | + data = { results: users } | ||
30 | + query.callback(data) | ||
31 | + | ||
32 | + initSelection: (element, callback) -> | ||
33 | + id = $(element).val() | ||
34 | + if id isnt "" | ||
35 | + Api.user(id, callback) | ||
36 | + | ||
37 | + | ||
38 | + formatResult: projectUserFormatResult | ||
39 | + formatSelection: projectUserFormatSelection | ||
40 | + dropdownCssClass: "ajax-project-users-dropdown" | ||
41 | + dropdownAutoWidth: true | ||
42 | + escapeMarkup: (m) -> # we do not want to escape markup since we are displaying html in results | ||
43 | + m |
app/assets/stylesheets/generic/selects.scss
@@ -79,6 +79,8 @@ select { | @@ -79,6 +79,8 @@ select { | ||
79 | margin-right: 10px; | 79 | margin-right: 10px; |
80 | } | 80 | } |
81 | 81 | ||
82 | -.ajax-users-dropdown .select2-search { | ||
83 | - padding-top: 4px; | 82 | +.ajax-users-dropdown, .ajax-project-users-dropdown { |
83 | + .select2-search { | ||
84 | + padding-top: 4px; | ||
85 | + } | ||
84 | } | 86 | } |
app/helpers/application_helper.rb
@@ -162,15 +162,6 @@ module ApplicationHelper | @@ -162,15 +162,6 @@ module ApplicationHelper | ||
162 | 162 | ||
163 | alias_method :url_to_image, :image_url | 163 | alias_method :url_to_image, :image_url |
164 | 164 | ||
165 | - def users_select_tag(id, opts = {}) | ||
166 | - css_class = "ajax-users-select " | ||
167 | - css_class << "multiselect " if opts[:multiple] | ||
168 | - css_class << (opts[:class] || '') | ||
169 | - value = opts[:selected] || '' | ||
170 | - | ||
171 | - hidden_field_tag(id, value, class: css_class) | ||
172 | - end | ||
173 | - | ||
174 | def body_data_page | 165 | def body_data_page |
175 | path = controller.controller_path.split('/') | 166 | path = controller.controller_path.split('/') |
176 | namespace = path.first if path.second | 167 | namespace = path.first if path.second |
@@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
1 | +module SelectsHelper | ||
2 | + def users_select_tag(id, opts = {}) | ||
3 | + css_class = "ajax-users-select " | ||
4 | + css_class << "multiselect " if opts[:multiple] | ||
5 | + css_class << (opts[:class] || '') | ||
6 | + value = opts[:selected] || '' | ||
7 | + | ||
8 | + hidden_field_tag(id, value, class: css_class) | ||
9 | + end | ||
10 | + | ||
11 | + def project_users_select_tag(id, opts = {}) | ||
12 | + css_class = "ajax-project-users-select " | ||
13 | + css_class << "multiselect " if opts[:multiple] | ||
14 | + css_class << (opts[:class] || '') | ||
15 | + value = opts[:selected] || '' | ||
16 | + | ||
17 | + hidden_field_tag(id, value, class: css_class) | ||
18 | + end | ||
19 | +end |
app/views/projects/issues/_issues.html.haml
@@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
6 | = form_tag bulk_update_project_issues_path(@project), method: :post do | 6 | = form_tag bulk_update_project_issues_path(@project), method: :post do |
7 | %span Update selected issues with | 7 | %span Update selected issues with |
8 | = select_tag('update[status]', options_for_select(['open', 'closed']), prompt: "Status") | 8 | = select_tag('update[status]', options_for_select(['open', 'closed']), prompt: "Status") |
9 | - = select_tag('update[assignee_id]', bulk_update_assignee_options, prompt: "Assignee") | 9 | + = project_users_select_tag('update[assignee_id]') |
10 | = select_tag('update[milestone_id]', bulk_update_milestone_options, prompt: "Milestone") | 10 | = select_tag('update[milestone_id]', bulk_update_milestone_options, prompt: "Milestone") |
11 | = hidden_field_tag 'update[issues_ids]', [] | 11 | = hidden_field_tag 'update[issues_ids]', [] |
12 | = hidden_field_tag :status, params[:status] | 12 | = hidden_field_tag :status, params[:status] |
lib/api/projects.rb
@@ -11,7 +11,7 @@ module API | @@ -11,7 +11,7 @@ module API | ||
11 | end | 11 | end |
12 | not_found! | 12 | not_found! |
13 | end | 13 | end |
14 | - | 14 | + |
15 | def map_public_to_visibility_level(attrs) | 15 | def map_public_to_visibility_level(attrs) |
16 | publik = attrs.delete(:public) | 16 | publik = attrs.delete(:public) |
17 | publik = [ true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON' ].include?(publik) | 17 | publik = [ true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON' ].include?(publik) |
@@ -308,6 +308,18 @@ module API | @@ -308,6 +308,18 @@ module API | ||
308 | projects = Project.where("(id in (?) OR visibility_level in (?)) AND (name LIKE (?))", ids, visibility_levels, "%#{params[:query]}%") | 308 | projects = Project.where("(id in (?) OR visibility_level in (?)) AND (name LIKE (?))", ids, visibility_levels, "%#{params[:query]}%") |
309 | present paginate(projects), with: Entities::Project | 309 | present paginate(projects), with: Entities::Project |
310 | end | 310 | end |
311 | + | ||
312 | + | ||
313 | + # Get a users list | ||
314 | + # | ||
315 | + # Example Request: | ||
316 | + # GET /users | ||
317 | + get ':id/users' do | ||
318 | + @users = User.where(id: user_project.team.users.map(&:id)) | ||
319 | + @users = @users.search(params[:search]) if params[:search].present? | ||
320 | + @users = paginate @users | ||
321 | + present @users, with: Entities::User | ||
322 | + end | ||
311 | end | 323 | end |
312 | end | 324 | end |
313 | end | 325 | end |