Commit 70e36862 authored by Jason Goodman's avatar Jason Goodman

Use group hierarchy share setting to filter search results for invite

No behavior changes because setting cannot be changed yet
parent bc6d1e35
......@@ -18,6 +18,7 @@ const Api = {
groupMembersPath: '/api/:version/groups/:id/members',
groupMilestonesPath: '/api/:version/groups/:id/milestones',
subgroupsPath: '/api/:version/groups/:id/subgroups',
descendantGroupsPath: '/api/:version/groups/:id/descendant_groups',
namespacesPath: '/api/:version/namespaces.json',
groupInvitationsPath: '/api/:version/groups/:id/invitations',
groupPackagesPath: '/api/:version/groups/:id/packages',
......
......@@ -5,6 +5,17 @@ import Api from './api';
import { loadCSSFile } from './lib/utils/css_utils';
import { select2AxiosTransport } from './lib/utils/select2_utils';
const groupsPath = (groupsFilter, parentGroupID) => {
switch (groupsFilter) {
case 'descendant_groups':
return Api.descendantGroupsPath.replace(':id', parentGroupID);
case 'subgroups':
return Api.subgroupsPath.replace(':id', parentGroupID);
default:
return Api.groupsPath;
}
};
const groupsSelect = () => {
loadCSSFile(gon.select2_css_path)
.then(() => {
......@@ -16,9 +27,7 @@ const groupsSelect = () => {
const allAvailable = $select.data('allAvailable');
const skipGroups = $select.data('skipGroups') || [];
const parentGroupID = $select.data('parentId');
const groupsPath = parentGroupID
? Api.subgroupsPath.replace(':id', parentGroupID)
: Api.groupsPath;
const groupsFilter = $select.data('groupsFilter');
$select.select2({
placeholder: __('Search for a group'),
......@@ -26,7 +35,7 @@ const groupsSelect = () => {
multiple: $select.hasClass('multiselect'),
minimumInputLength: 0,
ajax: {
url: Api.buildUrl(groupsPath),
url: Api.buildUrl(groupsPath(groupsFilter, parentGroupID)),
dataType: 'json',
quietMillis: 250,
transport: select2AxiosTransport,
......
- add_page_specific_style 'page_bundles/members'
- page_title _('Group members')
- groups_select_tag_data = @group.root_ancestor.namespace_settings.prevent_sharing_groups_outside_hierarchy ? { groups_filter: 'descendant_groups', parent_id: @group.root_ancestor.id, skip_groups: @skip_groups } : { skip_groups: @skip_groups }
.js-remove-member-modal
.row.gl-mt-3
......@@ -28,7 +29,7 @@
.tab-pane.active{ id: 'invite-member-pane', role: 'tabpanel' }
= render_invite_member_for_group(@group, @group_member.access_level)
.tab-pane{ id: 'invite-group-pane', role: 'tabpanel' }
= render 'shared/members/invite_group', submit_url: group_group_links_path(@group), access_levels: GroupMember.access_level_roles, default_access_level: @group_member.access_level, group_link_field: 'shared_with_group_id', group_access_field: 'shared_group_access'
= render 'shared/members/invite_group', submit_url: group_group_links_path(@group), access_levels: GroupMember.access_level_roles, default_access_level: @group_member.access_level, group_link_field: 'shared_with_group_id', group_access_field: 'shared_group_access', groups_select_tag_data: groups_select_tag_data
= render_if_exists 'groups/group_members/ldap_sync'
......
......@@ -51,11 +51,11 @@
.tab-pane.active{ id: 'invite-member-pane', role: 'tabpanel' }
= render 'shared/members/invite_member', submit_url: project_project_members_path(@project), access_levels: ProjectMember.access_level_roles, default_access_level: @project_member.access_level, can_import_members?: can_import_members?, import_path: import_project_project_members_path(@project)
.tab-pane{ id: 'invite-group-pane', role: 'tabpanel', class: ('active' if membership_locked?) }
= render 'shared/members/invite_group', submit_url: project_group_links_path(@project), access_levels: ProjectGroupLink.access_options, default_access_level: ProjectGroupLink.default_access, group_link_field: 'link_group_id', group_access_field: 'link_group_access'
= render 'shared/members/invite_group', submit_url: project_group_links_path(@project), access_levels: ProjectGroupLink.access_options, default_access_level: ProjectGroupLink.default_access, group_link_field: 'link_group_id', group_access_field: 'link_group_access', groups_select_tag_data: { skip_groups: @skip_groups }
- elsif !membership_locked?
.invite-member= render 'shared/members/invite_member', submit_url: project_project_members_path(@project), access_levels: ProjectMember.access_level_roles, default_access_level: @project_member.access_level, can_import_members?: can_import_members?, import_path: import_project_project_members_path(@project)
- elsif @project.allowed_to_share_with_group?
.invite-group= render 'shared/members/invite_group', access_levels: ProjectGroupLink.access_options, default_access_level: ProjectGroupLink.default_access, submit_url: project_group_links_path(@project), group_link_field: 'link_group_id', group_access_field: 'link_group_access'
.invite-group= render 'shared/members/invite_group', access_levels: ProjectGroupLink.access_options, default_access_level: ProjectGroupLink.default_access, submit_url: project_group_links_path(@project), group_link_field: 'link_group_id', group_access_field: 'link_group_access', groups_select_tag_data: { skip_groups: @skip_groups }
.js-project-members-list-app{ data: { members_data: project_members_app_data_json(@project,
members: @project_members,
group_links: @group_links,
......
......@@ -3,12 +3,14 @@
- submit_url = local_assigns[:submit_url]
- group_link_field = local_assigns[:group_link_field]
- group_access_field = local_assigns[:group_access_field]
- groups_select_tag_data = local_assigns[:groups_select_tag_data]
.row
.col-sm-12
= form_tag submit_url, class: 'invite-group-form js-requires-input', method: :post do
.form-group
= label_tag group_link_field, _("Select a group to invite"), class: "label-bold"
= groups_select_tag(group_link_field, data: { skip_groups: @skip_groups }, class: 'input-clamp qa-group-select-field', required: true)
= groups_select_tag(group_link_field, data: groups_select_tag_data, class: 'input-clamp qa-group-select-field', required: true)
.form-text.text-muted.gl-mb-3
= _('Group sharing provides access to all group members (including members who inherited group membership from a parent group).')
.form-group
......
......@@ -19,6 +19,6 @@
.form-group
= f.label :custom_project_templates_group_id, class: 'label-bold' do
= _('Custom project templates')
= groups_select_tag('group[custom_project_templates_group_id]', data: { parent_id: @group.id }, selected: @group.custom_project_templates_group_id, class: 'input-clamp allowClear qa-custom-project-template-select', multiple: false)
= groups_select_tag('group[custom_project_templates_group_id]', data: { groups_filter: 'subgroups', parent_id: @group.id }, selected: @group.custom_project_templates_group_id, class: 'input-clamp allowClear qa-custom-project-template-select', multiple: false)
= f.submit _('Save changes'), class: 'btn gl-button btn-success qa-save-changes-button'
......@@ -143,6 +143,58 @@ RSpec.describe 'Groups > Members > Manage groups', :js do
end
end
describe 'group search results' do
let_it_be(:group, refind: true) { create(:group) }
let_it_be(:group_within_hierarchy) { create(:group, parent: group) }
let_it_be(:group_outside_hierarchy) { create(:group) }
before_all do
group.add_owner(user)
group_within_hierarchy.add_owner(user)
group_outside_hierarchy.add_owner(user)
end
context 'when sharing with groups outside the hierarchy is enabled' do
context 'when the invite members group modal is disabled' do
before do
stub_feature_flags(invite_members_group_modal: false)
end
it 'shows groups within and outside the hierarchy in search results' do
visit group_group_members_path(group)
click_on 'Invite group'
click_on 'Search for a group'
expect(page).to have_text group_within_hierarchy.name
expect(page).to have_text group_outside_hierarchy.name
end
end
end
context 'when sharing with groups outside the hierarchy is disabled' do
before do
group.namespace_settings.update!(prevent_sharing_groups_outside_hierarchy: true)
end
context 'when the invite members group modal is disabled' do
before do
stub_feature_flags(invite_members_group_modal: false)
end
it 'shows only groups within the hierarchy in search results' do
visit group_group_members_path(group)
click_on 'Invite group'
click_on 'Search for a group'
expect(page).to have_text group_within_hierarchy.name
expect(page).not_to have_text group_outside_hierarchy.name
end
end
end
end
def add_group(id, role)
page.click_link 'Invite group'
page.within ".invite-group-form" do
......
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