diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index d62fae99c6b272d344c24c03e4451f868a542aa0..0ca0e8f35dd04ce5b56201583c054068c46d2069 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -150,14 +150,15 @@ const Api = { }, // Return group projects list. Filtered by query - groupProjects(groupId, query, callback) { + groupProjects(groupId, query, options, callback) { const url = Api.buildUrl(Api.groupProjectsPath).replace(':id', groupId); + const defaults = { + search: query, + per_page: 20, + }; return axios .get(url, { - params: { - search: query, - per_page: 20, - }, + params: Object.assign({}, defaults, options), }) .then(({ data }) => callback(data)); }, diff --git a/app/assets/javascripts/pages/search/show/search.js b/app/assets/javascripts/pages/search/show/search.js index 2e1fe78b3fa6baecd1864d151c159cfb7f1da865..e3e0ab91993eb6015344caa5e37b4c19eec24411 100644 --- a/app/assets/javascripts/pages/search/show/search.js +++ b/app/assets/javascripts/pages/search/show/search.js @@ -105,7 +105,7 @@ export default class Search { getProjectsData(term) { return new Promise((resolve) => { if (this.groupId) { - Api.groupProjects(this.groupId, term, resolve); + Api.groupProjects(this.groupId, term, {}, resolve); } else { Api.projects(term, { order_by: 'id', diff --git a/app/assets/javascripts/project_select.js b/app/assets/javascripts/project_select.js index 240dde5632568eb2e2cd31661049cf0a26cf7b71..bce7556bd40386fd66a7238521122a7c3b6b8e5c 100644 --- a/app/assets/javascripts/project_select.js +++ b/app/assets/javascripts/project_select.js @@ -47,7 +47,10 @@ export default function projectSelect() { projectsCallback = finalCallback; } if (_this.groupId) { - return Api.groupProjects(_this.groupId, query.term, projectsCallback); + return Api.groupProjects(_this.groupId, query.term, { + with_issues_enabled: _this.withIssuesEnabled, + with_merge_requests_enabled: _this.withMergeRequestsEnabled, + }, projectsCallback); } else { return Api.projects(query.term, { order_by: _this.orderBy, diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index 8037cf4b69d54eeb89caf6a17422b99cafc94bbd..5e1ae1dbe3884581d57edaec9d20abae8a073f70 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -9,7 +9,7 @@ = render 'shared/issuable/nav', type: :issues .nav-controls = render 'shared/issuable/feed_buttons' - = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", type: :issues + = render 'shared/new_project_item_select', path: 'issues/new', label: "New issue", type: :issues, with_feature_enabled: 'issues' = render 'shared/issuable/search_bar', type: :issues diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml index 4ccd16f3e111c0f7e3ae32362ff2aead8354d3dc..e2a317dbf673a0706b1270679473dab47313d0fe 100644 --- a/app/views/groups/merge_requests.html.haml +++ b/app/views/groups/merge_requests.html.haml @@ -7,7 +7,7 @@ = render 'shared/issuable/nav', type: :merge_requests - if current_user .nav-controls - = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", type: :merge_requests + = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request", type: :merge_requests, with_feature_enabled: 'merge_requests' = render 'shared/issuable/search_bar', type: :merge_requests diff --git a/app/views/shared/empty_states/_issues.html.haml b/app/views/shared/empty_states/_issues.html.haml index c7c33288e9d926c77a5e5e04f383ad8afc0f7b0f..2e26fe63d3ea4a87d17898cd360658da955b3699 100644 --- a/app/views/shared/empty_states/_issues.html.haml +++ b/app/views/shared/empty_states/_issues.html.haml @@ -16,7 +16,7 @@ - if has_button .text-center - if project_select_button - = render 'shared/new_project_item_select', path: 'issues/new', label: 'New issue', type: :issues + = render 'shared/new_project_item_select', path: 'issues/new', label: 'New issue', type: :issues, with_feature_enabled: 'issues' - else = link_to 'New issue', button_path, class: 'btn btn-success', title: 'New issue', id: 'new_issue_link' - else diff --git a/app/views/shared/empty_states/_merge_requests.html.haml b/app/views/shared/empty_states/_merge_requests.html.haml index 014220761a94a89b4d684d085ad90bcc200fda25..186139f352623926f63fad2b8e6827a662838059 100644 --- a/app/views/shared/empty_states/_merge_requests.html.haml +++ b/app/views/shared/empty_states/_merge_requests.html.haml @@ -15,7 +15,7 @@ = _("Interested parties can even contribute by pushing commits if they want to.") .text-center - if project_select_button - = render 'shared/new_project_item_select', path: 'merge_requests/new', label: _('New merge request'), type: :merge_requests + = render 'shared/new_project_item_select', path: 'merge_requests/new', label: _('New merge request'), type: :merge_requests, with_feature_enabled: 'merge_requests' - else = link_to _('New merge request'), button_path, class: 'btn btn-new', title: _('New merge request'), id: 'new_merge_request_link' - else diff --git a/changelogs/unreleased/47462-issues-disabled-group-page.yml b/changelogs/unreleased/47462-issues-disabled-group-page.yml new file mode 100644 index 0000000000000000000000000000000000000000..c8cad608cb38010892d4470277e48687817d721f --- /dev/null +++ b/changelogs/unreleased/47462-issues-disabled-group-page.yml @@ -0,0 +1,6 @@ +--- +title: Only show new issue / new merge request on group page when issues / merge requests + are enabled +merge_request: 19869 +author: Jan Beckmann +type: fixed diff --git a/doc/api/groups.md b/doc/api/groups.md index a48905f2f157b3fbd3e63a19e54e9bc6b1ca3fee..53d72509423f86b4dadc17a7ab63537e91a099aa 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -147,6 +147,8 @@ Parameters: | `simple` | boolean | no | Return only the ID, URL, name, and path of each project | | `owned` | boolean | no | Limit by projects owned by the current user | | `starred` | boolean | no | Limit by projects starred by the current user | +| `with_issues_enabled` | boolean | no | Limit by enabled issues feature | +| `with_merge_requests_enabled` | boolean | no | Limit by enabled merge requests feature | | `with_custom_attributes` | boolean | no | Include [custom attributes](custom_attributes.md) in response (admins only) | Example response: diff --git a/lib/api/groups.rb b/lib/api/groups.rb index c7f41aba8547d33a59d84211b6f79fa25f33454b..f633dd88d06904b76b93f131c7e674deb3fd9492 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -56,6 +56,8 @@ def find_groups(params, parent_id = nil) def find_group_projects(params) group = find_group!(params[:id]) projects = GroupProjectsFinder.new(group: group, current_user: current_user, params: project_finder_params).execute + projects = projects.with_issues_available_for_user(current_user) if params[:with_issues_enabled] + projects = projects.with_merge_requests_enabled if params[:with_merge_requests_enabled] projects = reorder_projects(projects) paginate(projects) end @@ -191,6 +193,8 @@ def present_groups(params, groups) desc: 'Return only the ID, URL, name, and path of each project' optional :owned, type: Boolean, default: false, desc: 'Limit by owned by authenticated user' optional :starred, type: Boolean, default: false, desc: 'Limit by starred status' + optional :with_issues_enabled, type: Boolean, default: false, desc: 'Limit by enabled issues feature' + optional :with_merge_requests_enabled, type: Boolean, default: false, desc: 'Limit by enabled merge requests feature' use :pagination use :with_custom_attributes diff --git a/spec/features/groups/empty_states_spec.rb b/spec/features/groups/empty_states_spec.rb index 04217fec06cb08c4a09f2d4a96ac21db808bc3f3..5828d833ae91c5599e53dabf3243fa2a28d342cd 100644 --- a/spec/features/groups/empty_states_spec.rb +++ b/spec/features/groups/empty_states_spec.rb @@ -59,6 +59,18 @@ end end + shared_examples "no projects" do + it 'displays an empty state' do + expect(page).to have_selector('.empty-state') + end + + it "does not show a new #{issuable_name} button" do + within '.empty-state' do + expect(page).not_to have_link("create #{issuable_name}") + end + end + end + context 'group without a project' do context 'group has a subgroup', :nested_groups do let(:subgroup) { create(:group, parent: group) } @@ -92,16 +104,18 @@ visit path end - it 'displays an empty state' do - expect(page).to have_selector('.empty-state') - end + it_behaves_like "no projects" + end + end - it "shows a new #{issuable_name} button" do - within '.empty-state' do - expect(page).not_to have_link("create #{issuable_name}") - end - end + context 'group has only a project with issues disabled' do + let(:project_with_issues_disabled) { create(:empty_project, :issues_disabled, group: group) } + + before do + visit path end + + it_behaves_like "no projects" end end end diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb index 111a24c0d94711582156977b23aa86f53635b95e..e131ded3688b13c77aee44b17c9557bf0dc11f1c 100644 --- a/spec/features/groups/issues_spec.rb +++ b/spec/features/groups/issues_spec.rb @@ -5,6 +5,7 @@ let(:group) { create(:group) } let(:project) { create(:project, :public, group: group)} + let(:project_with_issues_disabled) { create(:project, :issues_disabled, group: group) } let(:path) { issues_group_path(group) } context 'with shared examples' do @@ -76,4 +77,25 @@ end end end + + context 'projects with issues disabled' do + describe 'issue dropdown' do + let(:user_in_group) { create(:group_member, :master, user: create(:user), group: group ).user } + + before do + [project, project_with_issues_disabled].each { |project| project.add_master(user_in_group) } + sign_in(user_in_group) + visit issues_group_path(group) + end + + it 'shows projects only with issues feature enabled', :js do + find('.new-project-item-link').click + + page.within('.select2-results') do + expect(page).to have_content(project.full_name) + expect(page).not_to have_content(project_with_issues_disabled.full_name) + end + end + end + end end diff --git a/spec/features/groups/merge_requests_spec.rb b/spec/features/groups/merge_requests_spec.rb index 672ae785c2dbf23df324c3094acf4473e58a323c..921a447f6eeb512c240bccc0b6a7bd9e65cc0d63 100644 --- a/spec/features/groups/merge_requests_spec.rb +++ b/spec/features/groups/merge_requests_spec.rb @@ -56,4 +56,21 @@ expect(find('#js-dropdown-assignee .filter-dropdown')).not_to have_content(user2.name) end end + + describe 'new merge request dropdown' do + let(:project_with_merge_requests_disabled) { create(:project, :merge_requests_disabled, group: group) } + + before do + visit path + end + + it 'shows projects only with merge requests feature enabled', :js do + find('.new-project-item-link').click + + page.within('.select2-results') do + expect(page).to have_content(project.name_with_namespace) + expect(page).not_to have_content(project_with_merge_requests_disabled.name_with_namespace) + end + end + end end diff --git a/spec/javascripts/api_spec.js b/spec/javascripts/api_spec.js index c53b6da4b480efcea8e327274ea52d8c8ca7f2af..54cb6d84109c42beefb211990b11ed594104771e 100644 --- a/spec/javascripts/api_spec.js +++ b/spec/javascripts/api_spec.js @@ -242,7 +242,7 @@ describe('Api', () => { }, ]); - Api.groupProjects(groupId, query, response => { + Api.groupProjects(groupId, query, {}, response => { expect(response.length).toBe(1); expect(response[0].name).toBe('test'); done();