diff options
-rw-r--r-- | app/controllers/groups/group_members_controller.rb | 13 | ||||
-rw-r--r-- | app/models/member.rb | 4 | ||||
-rw-r--r-- | app/views/groups/group_members/index.html.haml | 23 | ||||
-rw-r--r-- | changelogs/unreleased/sh-break-out-invited-group-members.yml | 5 | ||||
-rw-r--r-- | spec/controllers/groups/group_members_controller_spec.rb | 33 | ||||
-rw-r--r-- | spec/factories/group_members.rb | 4 | ||||
-rw-r--r-- | spec/features/groups/members/manage_members_spec.rb | 2 | ||||
-rw-r--r-- | spec/models/member_spec.rb | 11 |
8 files changed, 90 insertions, 5 deletions
diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index f1d6fb00cfc..fc5cb3f0b5c 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -5,6 +5,8 @@ class Groups::GroupMembersController < Groups::ApplicationController include MembersPresentation include SortingHelper + MEMBER_PER_PAGE_LIMIT = 50 + def self.admin_not_required_endpoints %i[index leave request_access] end @@ -24,7 +26,14 @@ class Groups::GroupMembersController < Groups::ApplicationController @project = @group.projects.find(params[:project_id]) if params[:project_id] @members = GroupMembersFinder.new(@group).execute - @members = @members.non_invite unless can_manage_members + + if can_manage_members + @invited_members = @members.invite + @invited_members = @invited_members.search_invited(params[:search_invited]) if params[:search_invited].present? + @invited_members = present_members(@invited_members.page(params[:invited_members_page]).per(MEMBER_PER_PAGE_LIMIT)) + end + + @members = @members.non_invite @members = @members.search(params[:search]) if params[:search].present? @members = @members.sort_by_attribute(@sort) @@ -32,7 +41,7 @@ class Groups::GroupMembersController < Groups::ApplicationController @members = @members.filter_by_2fa(params[:two_factor]) end - @members = @members.page(params[:page]).per(50) + @members = @members.page(params[:page]).per(MEMBER_PER_PAGE_LIMIT) @members = present_members(@members) @requesters = present_members( diff --git a/app/models/member.rb b/app/models/member.rb index c7583434148..ada779f0583 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -107,6 +107,10 @@ class Member < ApplicationRecord joins(:user).merge(User.search(query)) end + def search_invited(query) + invite.where(['invite_email ILIKE ?', "%#{query}%"]) + end + def filter_by_2fa(value) case value when 'enabled' diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml index 021c0b6c429..ddbf89a5fb7 100644 --- a/app/views/groups/group_members/index.html.haml +++ b/app/views/groups/group_members/index.html.haml @@ -36,4 +36,25 @@ = render 'shared/members/sort_dropdown' %ul.content-list.members-list = render partial: 'shared/members/member', collection: @members, as: :member - = paginate @members, theme: 'gitlab' + = paginate @members, theme: 'gitlab' + + - if can_manage_members && @invited_members.exists? + .clearfix + %h5.member.existing-title + Invited members + .card + .card-header.flex-project-members-panel + %span.flex-project-title + Pending members to + %strong= @group.name + %span.badge.badge-pill= @invited_members.total_count + = form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form flex-project-members-form' do + .form-group + .position-relative.append-right-8 + = search_field_tag :search_invited, params[:search_invited], { placeholder: 'Find invited members by e-mail', class: 'form-control', spellcheck: false } + %button.member-search-btn{ type: "submit", "aria-label" => "Submit search" } + = icon("search") + = render 'shared/members/sort_dropdown' + %ul.content-list.invited-members-list + = render partial: 'shared/members/member', collection: @invited_members, as: :member + = paginate @invited_members, param_name: 'invited_members_page', theme: 'gitlab' diff --git a/changelogs/unreleased/sh-break-out-invited-group-members.yml b/changelogs/unreleased/sh-break-out-invited-group-members.yml new file mode 100644 index 00000000000..091f1d48843 --- /dev/null +++ b/changelogs/unreleased/sh-break-out-invited-group-members.yml @@ -0,0 +1,5 @@ +--- +title: Make it easier to find invited group members +merge_request: 28436 +author: +type: fixed diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb index 413598ddde0..908c564e761 100644 --- a/spec/controllers/groups/group_members_controller_spec.rb +++ b/spec/controllers/groups/group_members_controller_spec.rb @@ -16,6 +16,39 @@ describe Groups::GroupMembersController do expect(response).to have_gitlab_http_status(200) expect(response).to render_template(:index) end + + context 'user with owner access' do + let!(:invited) { create_list(:group_member, 3, :invited, group: group) } + + before do + group.add_owner(user) + sign_in(user) + end + + it 'assigns invited members' do + get :index, params: { group_id: group } + + expect(assigns(:invited_members).map(&:invite_email)).to match_array(invited.map(&:invite_email)) + end + + it 'restricts search to one email' do + get :index, params: { group_id: group, search_invited: invited.first.invite_email } + + expect(assigns(:invited_members).map(&:invite_email)).to match_array(invited.first.invite_email) + end + + it 'paginates invited list' do + stub_const('Groups::GroupMembersController::MEMBER_PER_PAGE_LIMIT', 2) + + get :index, params: { group_id: group, invited_members_page: 1 } + + expect(assigns(:invited_members).count).to eq(2) + + get :index, params: { group_id: group, invited_members_page: 2 } + + expect(assigns(:invited_members).count).to eq(1) + end + end end describe 'POST create' do diff --git a/spec/factories/group_members.rb b/spec/factories/group_members.rb index 3bf9cdef253..8dab6c71b06 100644 --- a/spec/factories/group_members.rb +++ b/spec/factories/group_members.rb @@ -16,7 +16,9 @@ FactoryBot.define do trait(:invited) do user_id nil invite_token 'xxx' - invite_email 'email@email.com' + sequence :invite_email do |n| + "email#{n}@email.com" + end end end end diff --git a/spec/features/groups/members/manage_members_spec.rb b/spec/features/groups/members/manage_members_spec.rb index 779fa74501a..48603058dac 100644 --- a/spec/features/groups/members/manage_members_spec.rb +++ b/spec/features/groups/members/manage_members_spec.rb @@ -98,7 +98,7 @@ describe 'Groups > Members > Manage members' do add_user('test@example.com', 'Reporter') - page.within(second_row) do + page.within('.content-list.invited-members-list') do expect(page).to have_content('test@example.com') expect(page).to have_content('Invited') expect(page).to have_button('Reporter') diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 782a84f922b..99b268b07e8 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -172,6 +172,17 @@ describe Member do it { expect(described_class.non_request).to include @accepted_request_member } end + describe '.search_invited' do + it 'returns only the matching e-mail' do + create(:group_member, :invited) + + invited = described_class.search_invited(@invited_member.invite_email) + + expect(invited.count).to eq(1) + expect(invited.first).to eq(@invited_member) + end + end + describe '.developers' do subject { described_class.developers.to_a } |