Add leave link to access_granted email
Allows users to leave a project/group that they have been added to. Add function to leave a namespace by url param If the `leave` param is present on a project/group show page, click the leave link.
This commit is contained in:
parent
7be2796e24
commit
1fb499de27
12 changed files with 110 additions and 8 deletions
22
app/assets/javascripts/namespaces/leave_by_url.js
Normal file
22
app/assets/javascripts/namespaces/leave_by_url.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
import Flash from '~/flash';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import { getParameterByName } from '~/lib/utils/common_utils';
|
||||
|
||||
const PARAMETER_NAME = 'leave';
|
||||
const LEAVE_LINK_SELECTOR = '.js-leave-link';
|
||||
|
||||
export default function leaveByUrl(namespaceType) {
|
||||
if (!namespaceType) throw new Error('namespaceType not provided');
|
||||
|
||||
const param = getParameterByName(PARAMETER_NAME);
|
||||
if (!param) return;
|
||||
|
||||
const leaveLink = document.querySelector(LEAVE_LINK_SELECTOR);
|
||||
if (leaveLink) {
|
||||
leaveLink.click();
|
||||
} else {
|
||||
Flash(
|
||||
sprintf(__('You do not have permission to leave this %{namespaceType}.'), { namespaceType }),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
import leaveByUrl from '~/namespaces/leave_by_url';
|
||||
import initGroupDetails from '../shared/group_details';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
leaveByUrl('group');
|
||||
initGroupDetails();
|
||||
});
|
||||
|
|
|
@ -9,6 +9,7 @@ import Activities from '~/activities';
|
|||
import { ajaxGet } from '~/lib/utils/common_utils';
|
||||
import GpgBadges from '~/gpg_badges';
|
||||
import initReadMore from '~/read_more';
|
||||
import leaveByUrl from '~/namespaces/leave_by_url';
|
||||
import Star from '../../../star';
|
||||
import notificationsDropdown from '../../../notifications_dropdown';
|
||||
|
||||
|
@ -44,4 +45,5 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
});
|
||||
|
||||
GpgBadges.fetch();
|
||||
leaveByUrl('project');
|
||||
});
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
- link_end = '</a>'.html_safe
|
||||
- source_type = member_source.model_name.singular
|
||||
- leave_link = polymorphic_url([member_source], leave: 1)
|
||||
- source_link = link_to(member_source.human_name, member_source.web_url, target: '_blank', rel: 'noopener noreferrer')
|
||||
|
||||
%p
|
||||
You have been granted #{member.human_access} access to the
|
||||
#{link_to member_source.human_name, member_source.web_url} #{member_source.model_name.singular}.
|
||||
= _('You have been granted %{access_level} access to the %{source_link} %{source_type}.').html_safe % { access_level: member.human_access, source_link: source_link, source_type: source_type }
|
||||
%p
|
||||
- leave_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: leave_link }
|
||||
= _('If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}.').html_safe % { source_type: source_type, leave_link_start: leave_link_start, link_end: link_end }
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
You have been granted <%= member.human_access %> access to the <%= member_source.human_name %> <%= member_source.model_name.singular %>.
|
||||
<% source_type = member_source.model_name.singular %>
|
||||
<%= _('You have been granted %{access_level} access to the %{source_name} %{source_type}.') % { access_level: member.human_access, source_name: member_source.human_name, source_type: source_type } %>
|
||||
|
||||
<%= member_source.web_url %>
|
||||
|
||||
<%= _('If this was a mistake you can leave the %{source_type}.') % { source_type: source_type } %>
|
||||
|
||||
<%= polymorphic_url([member_source], leave: 1) %>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
= link_to link_text, polymorphic_path([:leave, source, :members]),
|
||||
method: :delete,
|
||||
data: { confirm: leave_confirmation_message(source) },
|
||||
class: 'access-request-link'
|
||||
class: 'access-request-link js-leave-link'
|
||||
- elsif requester = source.requesters.find_by(user_id: current_user.id) # rubocop: disable CodeReuse/ActiveRecord
|
||||
= link_to _('Withdraw Access Request'), polymorphic_path([:leave, source, :members]),
|
||||
method: :delete,
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Leave project/group from access granted email
|
||||
merge_request: 27892
|
||||
author:
|
||||
type: added
|
|
@ -4854,6 +4854,12 @@ msgstr ""
|
|||
msgid "If enabled, access to projects will be validated on an external service using their classification label."
|
||||
msgstr ""
|
||||
|
||||
msgid "If this was a mistake you can %{leave_link_start}leave the %{source_type}%{link_end}."
|
||||
msgstr ""
|
||||
|
||||
msgid "If this was a mistake you can leave the %{source_type}."
|
||||
msgstr ""
|
||||
|
||||
msgid "If your HTTP repository is not publicly accessible, add authentication information to the URL: <code>https://username:password@gitlab.company.com/group/project.git</code>."
|
||||
msgstr ""
|
||||
|
||||
|
@ -10912,6 +10918,9 @@ msgstr ""
|
|||
msgid "You do not have any subscriptions yet"
|
||||
msgstr ""
|
||||
|
||||
msgid "You do not have permission to leave this %{namespaceType}."
|
||||
msgstr ""
|
||||
|
||||
msgid "You don't have any applications"
|
||||
msgstr ""
|
||||
|
||||
|
@ -10921,6 +10930,12 @@ msgstr ""
|
|||
msgid "You don't have any deployments right now."
|
||||
msgstr ""
|
||||
|
||||
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
|
||||
msgstr ""
|
||||
|
||||
msgid "You have been granted %{access_level} access to the %{source_name} %{source_type}."
|
||||
msgstr ""
|
||||
|
||||
msgid "You have been granted %{member_human_access} access to %{label}."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -21,6 +21,20 @@ describe 'Groups > Members > Leave group' do
|
|||
expect(group.users).not_to include(user)
|
||||
end
|
||||
|
||||
it 'guest leaves the group by url param', :js do
|
||||
group.add_guest(user)
|
||||
group.add_owner(other_user)
|
||||
|
||||
visit group_path(group, leave: 1)
|
||||
|
||||
page.accept_confirm
|
||||
|
||||
expect(find('.flash-notice')).to have_content "You left the \"#{group.full_name}\" group"
|
||||
expect(page).to have_content left_group_message(group)
|
||||
expect(current_path).to eq(dashboard_groups_path)
|
||||
expect(group.users).not_to include(user)
|
||||
end
|
||||
|
||||
it 'guest leaves the group as last member' do
|
||||
group.add_guest(user)
|
||||
|
||||
|
@ -32,7 +46,7 @@ describe 'Groups > Members > Leave group' do
|
|||
expect(group.users).not_to include(user)
|
||||
end
|
||||
|
||||
it 'owner leaves the group if they is not the last owner' do
|
||||
it 'owner leaves the group if they are not the last owner' do
|
||||
group.add_owner(user)
|
||||
group.add_owner(other_user)
|
||||
|
||||
|
@ -44,7 +58,7 @@ describe 'Groups > Members > Leave group' do
|
|||
expect(group.users).not_to include(user)
|
||||
end
|
||||
|
||||
it 'owner can not leave the group if they is a last owner' do
|
||||
it 'owner can not leave the group if they are the last owner' do
|
||||
group.add_owner(user)
|
||||
|
||||
visit group_path(group)
|
||||
|
@ -56,6 +70,14 @@ describe 'Groups > Members > Leave group' do
|
|||
expect(find(:css, '.project-members-page li', text: user.name)).not_to have_selector(:css, 'a.btn-remove')
|
||||
end
|
||||
|
||||
it 'owner can not leave the group by url param if they are the last owner', :js do
|
||||
group.add_owner(user)
|
||||
|
||||
visit group_path(group, leave: 1)
|
||||
|
||||
expect(find('.flash-alert')).to have_content 'You do not have permission to leave this group'
|
||||
end
|
||||
|
||||
def left_group_message(group)
|
||||
"You left the \"#{group.name}\""
|
||||
end
|
||||
|
|
|
@ -8,10 +8,17 @@ describe 'Projects > Members > Group member cannot leave group project' do
|
|||
before do
|
||||
group.add_developer(user)
|
||||
sign_in(user)
|
||||
visit project_path(project)
|
||||
end
|
||||
|
||||
it 'user does not see a "Leave project" link' do
|
||||
visit project_path(project)
|
||||
|
||||
expect(page).not_to have_content 'Leave project'
|
||||
end
|
||||
|
||||
it 'renders a flash message if attempting to leave by url', :js do
|
||||
visit project_path(project, leave: 1)
|
||||
|
||||
expect(find('.flash-alert')).to have_content 'You do not have permission to leave this project'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,13 +7,24 @@ describe 'Projects > Members > Member leaves project' do
|
|||
before do
|
||||
project.add_developer(user)
|
||||
sign_in(user)
|
||||
visit project_path(project)
|
||||
end
|
||||
|
||||
it 'user leaves project' do
|
||||
visit project_path(project)
|
||||
|
||||
click_link 'Leave project'
|
||||
|
||||
expect(current_path).to eq(dashboard_projects_path)
|
||||
expect(project.users.exists?(user.id)).to be_falsey
|
||||
end
|
||||
|
||||
it 'user leaves project by url param', :js do
|
||||
visit project_path(project, leave: 1)
|
||||
|
||||
page.accept_confirm
|
||||
|
||||
expect(find('.flash-notice')).to have_content "You left the \"#{project.full_name}\" project"
|
||||
expect(current_path).to eq(dashboard_projects_path)
|
||||
expect(project.users.exists?(user.id)).to be_falsey
|
||||
end
|
||||
end
|
||||
|
|
|
@ -701,6 +701,8 @@ describe Notify do
|
|||
is_expected.to have_body_text project.full_name
|
||||
is_expected.to have_body_text project.web_url
|
||||
is_expected.to have_body_text project_member.human_access
|
||||
is_expected.to have_body_text 'leave the project'
|
||||
is_expected.to have_body_text project_url(project, leave: 1)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1144,6 +1146,8 @@ describe Notify do
|
|||
is_expected.to have_body_text group.name
|
||||
is_expected.to have_body_text group.web_url
|
||||
is_expected.to have_body_text group_member.human_access
|
||||
is_expected.to have_body_text 'leave the group'
|
||||
is_expected.to have_body_text group_url(group, leave: 1)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue