Commit ea6bfaa8 authored by Kerri Miller's avatar Kerri Miller

Merge branch...

Merge branch '268129-add-the-invite-members-option-to-the-quick-menu-the-plus-icon-one-next-to-search' into 'master'

Add the invite members to the quick menu

See merge request gitlab-org/gitlab!50069
parents 05cdc665 1e12b126
...@@ -22,4 +22,34 @@ module InviteMembersHelper ...@@ -22,4 +22,34 @@ module InviteMembersHelper
def invite_group_members?(group) def invite_group_members?(group)
experiment_enabled?(:invite_members_empty_group_version_a) && Ability.allowed?(current_user, :admin_group_member, group) experiment_enabled?(:invite_members_empty_group_version_a) && Ability.allowed?(current_user, :admin_group_member, group)
end end
def dropdown_invite_members_link(form_model)
link_to invite_members_url(form_model),
data: {
'track-event': 'click_link',
'track-label': tracking_label(current_user),
'track-property': experiment_tracking_category_and_group(:invite_members_new_dropdown, subject: current_user)
} do
invite_member_link_content
end
end
private
def invite_members_url(form_model)
case form_model
when Project
project_project_members_path(form_model)
when Group
group_group_members_path(form_model)
end
end
def invite_member_link_content
text = s_('InviteMember|Invite members')
return text unless experiment_enabled?(:invite_members_new_dropdown)
"#{text} #{emoji_icon('shaking_hands', 'aria-hidden': true, class: 'gl-font-base gl-vertical-align-baseline')}".html_safe
end
end end
- return unless Gitlab::Experimentation.active?(:invite_members_new_dropdown) && can?(current_user, :admin_group_member, @group)
%li= dropdown_invite_members_link(@group)
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
= link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip qa-new-menu-toggle", id: "js-onboarding-new-project-link", title: _("New..."), ref: 'tooltip', aria: { label: _("New...") }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static' } do = link_to new_project_path, class: "header-new-dropdown-toggle has-tooltip qa-new-menu-toggle", id: "js-onboarding-new-project-link", title: _("New..."), ref: 'tooltip', aria: { label: _("New...") }, data: { toggle: 'dropdown', placement: 'bottom', container: 'body', display: 'static' } do
= sprite_icon('plus-square') = sprite_icon('plus-square')
= sprite_icon('chevron-down', css_class: 'caret-down') = sprite_icon('chevron-down', css_class: 'caret-down')
.dropdown-menu.dropdown-menu-right .dropdown-menu.dropdown-menu-right.dropdown-extended-height
%ul %ul
- if @group&.persisted? - if @group&.persisted?
- create_group_project = can?(current_user, :create_projects, @group) - create_group_project = can?(current_user, :create_projects, @group)
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
- if create_group_subgroup - if create_group_subgroup
%li= link_to _('New subgroup'), new_group_path(parent_id: @group.id) %li= link_to _('New subgroup'), new_group_path(parent_id: @group.id)
= render_if_exists 'layouts/header/create_epic_new_dropdown_item' = render_if_exists 'layouts/header/create_epic_new_dropdown_item'
= render 'layouts/header/group_invite_members_new_dropdown_item'
%li.divider %li.divider
%li.dropdown-bold-header GitLab %li.dropdown-bold-header GitLab
...@@ -33,6 +34,7 @@ ...@@ -33,6 +34,7 @@
%li= link_to _('New merge request'), project_new_merge_request_path(merge_project) %li= link_to _('New merge request'), project_new_merge_request_path(merge_project)
- if create_project_snippet - if create_project_snippet
%li= link_to _('New snippet'), new_project_snippet_path(@project) %li= link_to _('New snippet'), new_project_snippet_path(@project)
= render 'layouts/header/project_invite_members_new_dropdown_item'
%li.divider %li.divider
%li.dropdown-bold-header GitLab %li.dropdown-bold-header GitLab
- if current_user.can_create_project? - if current_user.can_create_project?
......
- return unless Gitlab::Experimentation.active?(:invite_members_new_dropdown) && can_import_members?
%li= dropdown_invite_members_link(@project)
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'layouts/header/_new_dropdown' do RSpec.describe 'layouts/header/_new_dropdown' do
let(:user) { create(:user) } let_it_be(:user) { create(:user) }
context 'group-specific links' do context 'group-specific links' do
let(:group) { create(:group) } let_it_be(:group) { create(:group) }
before do before do
allow(view).to receive(:current_user).and_return(user) allow(view).to receive(:current_user).and_return(user)
...@@ -17,10 +17,7 @@ RSpec.describe 'layouts/header/_new_dropdown' do ...@@ -17,10 +17,7 @@ RSpec.describe 'layouts/header/_new_dropdown' do
it 'does not have "New epic" link' do it 'does not have "New epic" link' do
render render
expect(rendered).not_to have_link( expect(rendered).not_to have_link('New epic', href: new_group_epic_path(group))
'New epic',
href: new_group_epic_path(group)
)
end end
context 'as a Group owner' do context 'as a Group owner' do
...@@ -36,10 +33,7 @@ RSpec.describe 'layouts/header/_new_dropdown' do ...@@ -36,10 +33,7 @@ RSpec.describe 'layouts/header/_new_dropdown' do
it 'has a "New epic" link' do it 'has a "New epic" link' do
render render
expect(rendered).to have_link( expect(rendered).to have_link('New epic', href: new_group_epic_path(group))
'New epic',
href: new_group_epic_path(group)
)
end end
end end
end end
......
...@@ -96,6 +96,9 @@ module Gitlab ...@@ -96,6 +96,9 @@ module Gitlab
}, },
pipelines_empty_state: { pipelines_empty_state: {
tracking_category: 'Growth::Activation::Experiment::PipelinesEmptyState' tracking_category: 'Growth::Activation::Experiment::PipelinesEmptyState'
},
invite_members_new_dropdown: {
tracking_category: 'Growth::Expansion::Experiment::InviteMembersNewDropdown'
} }
}.freeze }.freeze
......
...@@ -15,7 +15,7 @@ module Gitlab ...@@ -15,7 +15,7 @@ module Gitlab
included do included do
before_action :set_experimentation_subject_id_cookie, unless: :dnt_enabled? before_action :set_experimentation_subject_id_cookie, unless: :dnt_enabled?
helper_method :experiment_enabled?, :experiment_tracking_category_and_group helper_method :experiment_enabled?, :experiment_tracking_category_and_group, :tracking_label
end end
def set_experimentation_subject_id_cookie def set_experimentation_subject_id_cookie
......
...@@ -232,7 +232,7 @@ RSpec.describe ProjectsController do ...@@ -232,7 +232,7 @@ RSpec.describe ProjectsController do
before do before do
sign_in(user) sign_in(user)
allow(controller).to receive(:record_experiment_user).with(:invite_members_empty_project_version_a) allow(controller).to receive(:record_experiment_user)
end end
User.project_views.keys.each do |project_view| User.project_views.keys.each do |project_view|
......
...@@ -114,4 +114,69 @@ RSpec.describe InviteMembersHelper do ...@@ -114,4 +114,69 @@ RSpec.describe InviteMembersHelper do
end end
end end
end end
describe '#dropdown_invite_members_link' do
shared_examples_for 'dropdown invite members link' do
let(:link_regex) do
/data-track-event="click_link".*data-track-property="_track_property_".*Invite members/
end
before do
allow(helper).to receive(:experiment_tracking_category_and_group) { '_track_property_' }
allow(helper).to receive(:tracking_label).with(owner)
allow(helper).to receive(:current_user) { owner }
end
it 'records the experiment' do
allow(helper).to receive(:experiment_enabled?)
helper.dropdown_invite_members_link(form_model)
expect(helper).to have_received(:experiment_tracking_category_and_group)
.with(:invite_members_new_dropdown, subject: owner)
end
context 'with experiment enabled' do
before do
allow(helper).to receive(:experiment_enabled?).with(:invite_members_new_dropdown) { true }
end
it 'returns link' do
link = helper.dropdown_invite_members_link(form_model)
expect(link).to match(link_regex)
expect(link).to include(link_href)
expect(link).to include('gl-emoji')
end
end
context 'with no experiment enabled' do
before do
allow(helper).to receive(:experiment_enabled?).with(:invite_members_new_dropdown) { false }
end
it 'returns link' do
link = helper.dropdown_invite_members_link(form_model)
expect(link).to match(link_regex)
expect(link).to include(link_href)
expect(link).not_to include('gl-emoji')
end
end
end
context 'with a project' do
let_it_be(:form_model) { project }
let(:link_href) { "href=\"#{project_project_members_path(form_model)}\"" }
it_behaves_like 'dropdown invite members link'
end
context 'with a group' do
let_it_be(:form_model) { create(:group) }
let(:link_href) { "href=\"#{group_group_members_path(form_model)}\"" }
it_behaves_like 'dropdown invite members link'
end
end
end end
...@@ -3,10 +3,42 @@ ...@@ -3,10 +3,42 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'layouts/header/_new_dropdown' do RSpec.describe 'layouts/header/_new_dropdown' do
let(:user) { create(:user) } let_it_be(:user) { create(:user) }
shared_examples_for 'invite member quick link' do
context 'when an experiment is active' do
before do
allow(Gitlab::Experimentation).to receive(:active?).and_return(true)
allow(view).to receive(:experiment_tracking_category_and_group)
allow(view).to receive(:tracking_label).with(user)
end
context 'with ability to invite members' do
it { is_expected.to have_link('Invite members', href: href) }
it 'records the experiment' do
subject
expect(view).to have_received(:experiment_tracking_category_and_group)
.with(:invite_members_new_dropdown, subject: user)
expect(view).to have_received(:tracking_label).with(user)
end
end
context 'without ability to invite members' do
let(:invite_member) { false }
it { is_expected.not_to have_link('Invite members') }
end
end
context 'when experiment is not active' do
it { is_expected.not_to have_link('Invite members') }
end
end
context 'group-specific links' do context 'group-specific links' do
let(:group) { create(:group) } let_it_be(:group) { create(:group) }
before do before do
stub_current_user(user) stub_current_user(user)
...@@ -22,25 +54,39 @@ RSpec.describe 'layouts/header/_new_dropdown' do ...@@ -22,25 +54,39 @@ RSpec.describe 'layouts/header/_new_dropdown' do
it 'has a "New project" link' do it 'has a "New project" link' do
render render
expect(rendered).to have_link( expect(rendered).to have_link('New project', href: new_project_path(namespace_id: group.id))
'New project',
href: new_project_path(namespace_id: group.id)
)
end end
it 'has a "New subgroup" link' do it 'has a "New subgroup" link' do
render render
expect(rendered).to have_link( expect(rendered).to have_link('New subgroup', href: new_group_path(parent_id: group.id))
'New subgroup', end
href: new_group_path(parent_id: group.id) end
)
describe 'invite members quick link' do
let(:href) { group_group_members_path(group) }
let(:invite_member) { true }
before do
allow(view).to receive(:can?).with(user, :create_projects, group).and_return(true)
allow(view).to receive(:can?).with(user, :admin_group_member, group).and_return(invite_member)
allow(view).to receive(:can_import_members?).and_return(invite_member)
allow(view).to receive(:experiment_enabled?)
end
subject do
render
rendered
end end
it_behaves_like 'invite member quick link'
end end
end end
context 'project-specific links' do context 'project-specific links' do
let(:project) { create(:project, creator: user, namespace: user.namespace) } let_it_be(:project) { create(:project, creator: user, namespace: user.namespace) }
before do before do
assign(:project, project) assign(:project, project)
...@@ -54,33 +100,24 @@ RSpec.describe 'layouts/header/_new_dropdown' do ...@@ -54,33 +100,24 @@ RSpec.describe 'layouts/header/_new_dropdown' do
it 'has a "New issue" link' do it 'has a "New issue" link' do
render render
expect(rendered).to have_link( expect(rendered).to have_link('New issue', href: new_project_issue_path(project))
'New issue',
href: new_project_issue_path(project)
)
end end
it 'has a "New merge request" link' do it 'has a "New merge request" link' do
render render
expect(rendered).to have_link( expect(rendered).to have_link('New merge request', href: project_new_merge_request_path(project))
'New merge request',
href: project_new_merge_request_path(project)
)
end end
it 'has a "New snippet" link' do it 'has a "New snippet" link' do
render render
expect(rendered).to have_link( expect(rendered).to have_link('New snippet', href: new_project_snippet_path(project))
'New snippet',
href: new_project_snippet_path(project)
)
end end
end end
context 'as a Project guest' do context 'as a Project guest' do
let(:guest) { create(:user) } let_it_be(:guest) { create(:user) }
before do before do
stub_current_user(guest) stub_current_user(guest)
...@@ -96,11 +133,27 @@ RSpec.describe 'layouts/header/_new_dropdown' do ...@@ -96,11 +133,27 @@ RSpec.describe 'layouts/header/_new_dropdown' do
it 'has no "New snippet" link' do it 'has no "New snippet" link' do
render render
expect(rendered).not_to have_link( expect(rendered).not_to have_link('New snippet', href: new_project_snippet_path(project))
'New snippet', end
href: new_project_snippet_path(project) end
)
describe 'invite members quick link' do
let(:invite_member) { true }
let(:href) { project_project_members_path(project) }
before do
allow(view).to receive(:can_import_members?).and_return(invite_member)
stub_current_user(user)
allow(view).to receive(:experiment_enabled?)
end
subject do
render
rendered
end end
it_behaves_like 'invite member quick link'
end end
end end
...@@ -128,7 +181,7 @@ RSpec.describe 'layouts/header/_new_dropdown' do ...@@ -128,7 +181,7 @@ RSpec.describe 'layouts/header/_new_dropdown' do
end end
context 'when the user is not allowed to create snippets' do context 'when the user is not allowed to create snippets' do
let(:user) { create(:user, :external)} let(:user) { create(:user, :external) }
it 'has no "New snippet" link' do it 'has no "New snippet" link' do
render render
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment