diff --git a/app/assets/javascripts/filtered_search/dropdown_user.js b/app/assets/javascripts/filtered_search/dropdown_user.js index 7246ccbb281..720fbc87ea0 100644 --- a/app/assets/javascripts/filtered_search/dropdown_user.js +++ b/app/assets/javascripts/filtered_search/dropdown_user.js @@ -15,6 +15,7 @@ class DropdownUser extends gl.FilteredSearchDropdown { params: { per_page: 20, active: true, + group_id: this.getGroupId(), project_id: this.getProjectId(), current_user: true, }, @@ -47,6 +48,10 @@ class DropdownUser extends gl.FilteredSearchDropdown { super.renderContent(forceShowList); } + getGroupId() { + return this.input.getAttribute('data-group-id'); + } + getProjectId() { return this.input.getAttribute('data-project-id'); } diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml index c4ed7f6e750..d3f0aa2d339 100644 --- a/app/views/shared/issuable/_filter.html.haml +++ b/app/views/shared/issuable/_filter.html.haml @@ -11,13 +11,13 @@ - if params[:author_id].present? = hidden_field_tag(:author_id, params[:author_id]) = dropdown_tag(user_dropdown_label(params[:author_id], "Author"), options: { toggle_class: "js-user-search js-filter-submit js-author-search", title: "Filter by author", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-author js-filter-submit", - placeholder: "Search authors", data: { any_user: "Any Author", first_user: current_user.try(:username), current_user: true, project_id: @project.try(:id), selected: params[:author_id], field_name: "author_id", default_label: "Author" } }) + placeholder: "Search authors", data: { any_user: "Any Author", first_user: current_user&.username, current_user: true, project_id: @project&.id, group_id: @group&.id, selected: params[:author_id], field_name: "author_id", default_label: "Author" } }) .filter-item.inline - if params[:assignee_id].present? = hidden_field_tag(:assignee_id, params[:assignee_id]) = dropdown_tag(user_dropdown_label(params[:assignee_id], "Assignee"), options: { toggle_class: "js-user-search js-filter-submit js-assignee-search", title: "Filter by assignee", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-assignee js-filter-submit", - placeholder: "Search assignee", data: { any_user: "Any Assignee", first_user: current_user.try(:username), null_user: true, current_user: true, project_id: @project.try(:id), group_id: @group&.id, selected: params[:assignee_id], field_name: "assignee_id", default_label: "Assignee" } }) + placeholder: "Search assignee", data: { any_user: "Any Assignee", first_user: current_user&.username, null_user: true, current_user: true, project_id: @project&.id, group_id: @group&.id, selected: params[:assignee_id], field_name: "assignee_id", default_label: "Assignee" } }) .filter-item.inline.milestone-filter = render "shared/issuable/milestone_dropdown", selected: finder.milestones.try(:first), name: :milestone_title, show_any: true, show_upcoming: true, show_started: true diff --git a/changelogs/unreleased/20824-scope-users-to-members-in-group-issuable-list.yml b/changelogs/unreleased/20824-scope-users-to-members-in-group-issuable-list.yml new file mode 100644 index 00000000000..245b8129de8 --- /dev/null +++ b/changelogs/unreleased/20824-scope-users-to-members-in-group-issuable-list.yml @@ -0,0 +1,5 @@ +--- +title: Return only group's members in user dropdowns on issuables list pages +merge_request: 14249 +author: +type: changed diff --git a/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb b/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb new file mode 100644 index 00000000000..5ed4f3ad2bc --- /dev/null +++ b/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +feature 'Groups > User sees users dropdowns in issuables list' do + let(:entity) { create(:group) } + let(:user_in_dropdown) { create(:user) } + let!(:user_not_in_dropdown) { create(:user) } + let!(:project) { create(:project, group: entity) } + + before do + entity.add_developer(user_in_dropdown) + end + + it_behaves_like 'issuable user dropdown behaviors' do + let(:issuable) { create(:issue, project: project) } + let(:issuables_path) { issues_group_path(entity) } + end + + it_behaves_like 'issuable user dropdown behaviors' do + let(:issuable) { create(:merge_request, source_project: project) } + let(:issuables_path) { merge_requests_group_path(entity) } + end +end diff --git a/spec/javascripts/filtered_search/dropdown_user_spec.js b/spec/javascripts/filtered_search/dropdown_user_spec.js index b3c9bca64cc..02415485d19 100644 --- a/spec/javascripts/filtered_search/dropdown_user_spec.js +++ b/spec/javascripts/filtered_search/dropdown_user_spec.js @@ -10,6 +10,7 @@ describe('Dropdown User', () => { beforeEach(() => { spyOn(gl.DropdownUser.prototype, 'bindEvents').and.callFake(() => {}); spyOn(gl.DropdownUser.prototype, 'getProjectId').and.callFake(() => {}); + spyOn(gl.DropdownUser.prototype, 'getGroupId').and.callFake(() => {}); spyOn(gl.DropdownUtils, 'getSearchInput').and.callFake(() => {}); dropdownUser = new gl.DropdownUser({ @@ -38,6 +39,7 @@ describe('Dropdown User', () => { beforeEach(() => { spyOn(gl.DropdownUser.prototype, 'bindEvents').and.callFake(() => {}); spyOn(gl.DropdownUser.prototype, 'getProjectId').and.callFake(() => {}); + spyOn(gl.DropdownUser.prototype, 'getGroupId').and.callFake(() => {}); }); it('should return endpoint', () => { diff --git a/spec/support/shared_examples/features/issuables_user_dropdown_behaviors_shared_examples.rb b/spec/support/shared_examples/features/issuables_user_dropdown_behaviors_shared_examples.rb new file mode 100644 index 00000000000..c92c7f603d6 --- /dev/null +++ b/spec/support/shared_examples/features/issuables_user_dropdown_behaviors_shared_examples.rb @@ -0,0 +1,21 @@ +shared_examples 'issuable user dropdown behaviors' do + include FilteredSearchHelpers + + before do + issuable # ensure we have at least one issuable + sign_in(user_in_dropdown) + end + + %w[author assignee].each do |dropdown| + describe "#{dropdown} dropdown", :js do + it 'only includes members of the project/group' do + visit issuables_path + + filtered_search.set("#{dropdown}:") + + expect(find("#js-dropdown-#{dropdown} .filter-dropdown")).to have_content(user_in_dropdown.name) + expect(find("#js-dropdown-#{dropdown} .filter-dropdown")).not_to have_content(user_not_in_dropdown.name) + end + end + end +end diff --git a/spec/support/project_features_apply_to_issuables_shared_examples.rb b/spec/support/shared_examples/features/project_features_apply_to_issuables_shared_examples.rb similarity index 100% rename from spec/support/project_features_apply_to_issuables_shared_examples.rb rename to spec/support/shared_examples/features/project_features_apply_to_issuables_shared_examples.rb