diff --git a/app/assets/javascripts/api.js.coffee b/app/assets/javascripts/api.js.coffee index 5f4a38ebbd00735d88cb1be2f680871bdf762611..fafa5cdfaa4c83d329af632c1269a605568c2c1d 100644 --- a/app/assets/javascripts/api.js.coffee +++ b/app/assets/javascripts/api.js.coffee @@ -3,6 +3,7 @@ user_path: "/api/:version/users/:id.json" notes_path: "/api/:version/projects/:id/notes.json" namespaces_path: "/api/:version/namespaces.json" + project_users_path: "/api/:version/projects/:id/users.json" # Get 20 (depends on api) recent notes # and sort the ascending from oldest to newest @@ -50,6 +51,23 @@ ).done (users) -> callback(users) + # Return project users list. Filtered by query + # Only active users retrieved + projectUsers: (project_id, query, callback) -> + url = Api.buildUrl(Api.project_users_path) + url = url.replace(':id', project_id) + + $.ajax( + url: url + data: + private_token: gon.api_token + search: query + per_page: 20 + active: true + dataType: "json" + ).done (users) -> + callback(users) + # Return namespaces list. Filtered by query namespaces: (query, callback) -> url = Api.buildUrl(Api.namespaces_path) diff --git a/app/assets/javascripts/project_users_select.js.coffee b/app/assets/javascripts/project_users_select.js.coffee new file mode 100644 index 0000000000000000000000000000000000000000..fbb1293b28926e5a6da2f6cc5c7d8095b816f675 --- /dev/null +++ b/app/assets/javascripts/project_users_select.js.coffee @@ -0,0 +1,43 @@ +$ -> + projectUserFormatResult = (user) -> + if user.avatar_url + avatar = user.avatar_url + else if gon.gravatar_enabled + avatar = gon.gravatar_url + avatar = avatar.replace('%{hash}', md5(user.email)) + avatar = avatar.replace('%{size}', '24') + else + avatar = gon.relative_url_root + "/assets/no_avatar.png" + + "<div class='user-result'> + <div class='user-image'><img class='avatar s24' src='#{avatar}'></div> + <div class='user-name'>#{user.name}</div> + <div class='user-username'>#{user.username}</div> + </div>" + + projectUserFormatSelection = (user) -> + user.name + + $('.ajax-project-users-select').each (i, select) -> + project_id = $('body').data('project-id') + $(select).select2 + placeholder: "Search for a user" + multiple: $(select).hasClass('multiselect') + minimumInputLength: 0 + query: (query) -> + Api.projectUsers project_id, query.term, (users) -> + data = { results: users } + query.callback(data) + + initSelection: (element, callback) -> + id = $(element).val() + if id isnt "" + Api.user(id, callback) + + + formatResult: projectUserFormatResult + formatSelection: projectUserFormatSelection + dropdownCssClass: "ajax-project-users-dropdown" + dropdownAutoWidth: true + escapeMarkup: (m) -> # we do not want to escape markup since we are displaying html in results + m diff --git a/app/assets/stylesheets/generic/selects.scss b/app/assets/stylesheets/generic/selects.scss index a257049bacf7d1786af91a5f639b14007216185a..0c7852925b87220e5fada997f700138c662afae5 100644 --- a/app/assets/stylesheets/generic/selects.scss +++ b/app/assets/stylesheets/generic/selects.scss @@ -79,6 +79,8 @@ select { margin-right: 10px; } -.ajax-users-dropdown .select2-search { - padding-top: 4px; +.ajax-users-dropdown, .ajax-project-users-dropdown { + .select2-search { + padding-top: 4px; + } } diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 1550e8b7e056cbe70520900ebd97372d631fdad2..4e7d01acd2af02990cdd5a52a508999241a36cc5 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -162,15 +162,6 @@ module ApplicationHelper alias_method :url_to_image, :image_url - def users_select_tag(id, opts = {}) - css_class = "ajax-users-select " - css_class << "multiselect " if opts[:multiple] - css_class << (opts[:class] || '') - value = opts[:selected] || '' - - hidden_field_tag(id, value, class: css_class) - end - def body_data_page path = controller.controller_path.split('/') namespace = path.first if path.second diff --git a/app/helpers/selects_helper.rb b/app/helpers/selects_helper.rb new file mode 100644 index 0000000000000000000000000000000000000000..0668a164809c78a60da4f1f55ffb456777000d28 --- /dev/null +++ b/app/helpers/selects_helper.rb @@ -0,0 +1,19 @@ +module SelectsHelper + def users_select_tag(id, opts = {}) + css_class = "ajax-users-select " + css_class << "multiselect " if opts[:multiple] + css_class << (opts[:class] || '') + value = opts[:selected] || '' + + hidden_field_tag(id, value, class: css_class) + end + + def project_users_select_tag(id, opts = {}) + css_class = "ajax-project-users-select " + css_class << "multiselect " if opts[:multiple] + css_class << (opts[:class] || '') + value = opts[:selected] || '' + + hidden_field_tag(id, value, class: css_class) + end +end diff --git a/app/views/projects/issues/_issues.html.haml b/app/views/projects/issues/_issues.html.haml index fc4128a829914ef1687c0c8c3cfde8fda60b68ef..66e8efb7df0fa53ac24d5637480530066c8d64b6 100644 --- a/app/views/projects/issues/_issues.html.haml +++ b/app/views/projects/issues/_issues.html.haml @@ -6,7 +6,7 @@ = form_tag bulk_update_project_issues_path(@project), method: :post do %span Update selected issues with = select_tag('update[status]', options_for_select(['open', 'closed']), prompt: "Status") - = select_tag('update[assignee_id]', bulk_update_assignee_options, prompt: "Assignee") + = project_users_select_tag('update[assignee_id]') = select_tag('update[milestone_id]', bulk_update_milestone_options, prompt: "Milestone") = hidden_field_tag 'update[issues_ids]', [] = hidden_field_tag :status, params[:status] diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 888aa7e77d225db669d0d262dd6ae21d1da84ba7..bcca69ff49a3c5988a02cd0a32a8a795e675fca6 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -11,7 +11,7 @@ module API end not_found! end - + def map_public_to_visibility_level(attrs) publik = attrs.delete(:public) publik = [ true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON' ].include?(publik) @@ -308,6 +308,18 @@ module API projects = Project.where("(id in (?) OR visibility_level in (?)) AND (name LIKE (?))", ids, visibility_levels, "%#{params[:query]}%") present paginate(projects), with: Entities::Project end + + + # Get a users list + # + # Example Request: + # GET /users + get ':id/users' do + @users = User.where(id: user_project.team.users.map(&:id)) + @users = @users.search(params[:search]) if params[:search].present? + @users = paginate @users + present @users, with: Entities::User + end end end end