From 0dc0796797ccbe95e84a50a53834e54bd3b32878 Mon Sep 17 00:00:00 2001 From: Deepika Guliani Date: Wed, 10 Dec 2025 14:55:14 +1100 Subject: [PATCH 1/2] Add work item settings page in admin instance :Behind FF work_item_configurable_types --- .../admin/application_settings_controller.rb | 9 +++++++++ config/routes/admin.rb | 2 +- .../ee/admin/application_settings_controller.rb | 7 ++++++- .../admin/application_settings/work_item.html.haml | 6 ++++++ .../ee/sidebars/admin/menus/admin_settings_menu.rb | 13 +++++++++++++ locale/gitlab.pot | 3 +++ 6 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 ee/app/views/admin/application_settings/work_item.html.haml diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 3ff466b6ea3310..d3e36464ceb61b 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -12,6 +12,7 @@ class ApplicationSettingsController < Admin::ApplicationController # cache might be stale immediately after an update. # https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30233 before_action :set_application_setting, except: :integrations + before_action :should_show_work_item_type_setting, only: [:work_item] before_action :disable_query_limiting, only: [:usage_data] before_action :prerecorded_service_ping_data, only: [:metrics_and_profiling] # rubocop:disable Rails/LexicallyScopedActionFilter @@ -67,6 +68,10 @@ def update perform_update end + def work_item + perform_update + end + def usage_data return not_found unless prerecorded_service_ping_data.present? @@ -259,6 +264,10 @@ def remove_blank_params_for!(*keys) params[:application_setting].delete_if { |setting, value| setting.to_sym.in?(keys) && value.blank? } end + def should_show_work_item_type_setting + render_404 unless Gitlab.ee? && ::Feature.enabled?(:work_item_configurable_types, :instance) + end + # overridden in EE def valid_setting_panels VALID_SETTING_PANELS diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 6edba232c43da5..9fe628722fee78 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -185,7 +185,7 @@ put :reset_error_tracking_access_token put :clear_repository_check_states put :reset_vscode_extension_marketplace_extension_host_domain - match :general, :integrations, :repository, :ci_cd, :reporting, :metrics_and_profiling, :network, :preferences, :search, :usage_quotas, via: [:get, :patch] + match :general, :integrations, :repository, :ci_cd, :reporting, :metrics_and_profiling, :network, :preferences, :search, :usage_quotas, :work_item, via: [:get, :patch] get :lets_encrypt_terms_of_service get :slack_app_manifest_download, format: :json get :slack_app_manifest_share diff --git a/ee/app/controllers/ee/admin/application_settings_controller.rb b/ee/app/controllers/ee/admin/application_settings_controller.rb index d6798b1aa39159..fc500c7f4124a6 100644 --- a/ee/app/controllers/ee/admin/application_settings_controller.rb +++ b/ee/app/controllers/ee/admin/application_settings_controller.rb @@ -21,6 +21,7 @@ module ApplicationSettingsController before_action :indexing_status, only: [:search] before_action :search_error_if_version_incompatible, only: [:search], if: -> { es_helper.ping? } before_action :search_outdated_code_analyzer_detected, only: [:search], if: -> { es_helper.ping? } + before_action :should_show_work_item_type_setting, only: [:work_item] before_action :new_license, only: [:general] before_action :scim_token, only: [:general] @@ -91,6 +92,10 @@ def search_outdated_code_analyzer_detected log_exception(e) end + def should_show_work_item_type_setting + render_404 unless ::Feature.enabled?(:work_item_configurable_types, :instance) + end + def scim_token scim_token = ScimOauthAccessToken.find_for_instance @@ -126,7 +131,7 @@ def indexing_status end end - EE_VALID_SETTING_PANELS = %w[search templates security_and_compliance namespace_storage].freeze + EE_VALID_SETTING_PANELS = %w[search templates security_and_compliance namespace_storage work_item].freeze EE_VALID_SETTING_PANELS.each do |action| define_method(action) { perform_update if submitted? } diff --git a/ee/app/views/admin/application_settings/work_item.html.haml b/ee/app/views/admin/application_settings/work_item.html.haml new file mode 100644 index 00000000000000..2ff57bff952954 --- /dev/null +++ b/ee/app/views/admin/application_settings/work_item.html.haml @@ -0,0 +1,6 @@ +- breadcrumb_title s_('WorkItem|Work item settings') +- page_title s_('WorkItem|Work item settings') +- add_page_specific_style 'page_bundles/settings' +- @force_desktop_expanded_sidebar = true + +%h2.gl-heading-2.gl-mt-2= _('Work item settings') diff --git a/ee/lib/ee/sidebars/admin/menus/admin_settings_menu.rb b/ee/lib/ee/sidebars/admin/menus/admin_settings_menu.rb index 70d161956479a5..a54c3954cd0619 100644 --- a/ee/lib/ee/sidebars/admin/menus/admin_settings_menu.rb +++ b/ee/lib/ee/sidebars/admin/menus/admin_settings_menu.rb @@ -19,11 +19,24 @@ def configure_menu_items insert_item_after(:security_and_compliance_menu_item, analytics_menu_item) insert_item_after(:admin_preferences, usage_quotas_menu_item) + if ::Feature.enabled?(:work_item_configurable_types, :instance) + insert_item_after(:admin_security_and_compliance, work_item_settings_menu_item) + end + true end private + def work_item_settings_menu_item + ::Sidebars::MenuItem.new( + title: _('Work items'), + link: work_item_admin_application_settings_path, + active_routes: { path: 'admin/work_items' }, + container_html_options: { 'data-testid': 'admin-work-item-settings' } + ) + end + def roles_and_permissions_menu_item return ::Sidebars::NilMenuItem.new(item_id: :roles_and_permissions) unless roles_and_permissions_available? diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 485ef93bf8f2e2..d345e0c3328454 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -76565,6 +76565,9 @@ msgstr "" msgid "Work item not supported" msgstr "" +msgid "Work item settings" +msgstr "" + msgid "Work item type %{work_item_type_name} can only have a maximum of %{limit} active custom fields." msgstr "" -- GitLab From c5ccbe9100656e01a304b348bd090f206a7c774f Mon Sep 17 00:00:00 2001 From: Deepika Guliani Date: Tue, 16 Dec 2025 14:31:41 +1100 Subject: [PATCH 2/2] Apply reviewer comments --- .../admin/application_settings_controller.rb | 9 ------ config/routes/admin.rb | 2 +- .../admin/application_settings_controller.rb | 6 ++-- ee/config/routes/admin.rb | 2 +- .../application_settings_controller_spec.rb | 31 +++++++++++++++++++ locale/gitlab.pot | 3 ++ .../application_settings_controller_spec.rb | 30 ++++++++++++++++++ 7 files changed, 69 insertions(+), 14 deletions(-) diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index d3e36464ceb61b..3ff466b6ea3310 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -12,7 +12,6 @@ class ApplicationSettingsController < Admin::ApplicationController # cache might be stale immediately after an update. # https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30233 before_action :set_application_setting, except: :integrations - before_action :should_show_work_item_type_setting, only: [:work_item] before_action :disable_query_limiting, only: [:usage_data] before_action :prerecorded_service_ping_data, only: [:metrics_and_profiling] # rubocop:disable Rails/LexicallyScopedActionFilter @@ -68,10 +67,6 @@ def update perform_update end - def work_item - perform_update - end - def usage_data return not_found unless prerecorded_service_ping_data.present? @@ -264,10 +259,6 @@ def remove_blank_params_for!(*keys) params[:application_setting].delete_if { |setting, value| setting.to_sym.in?(keys) && value.blank? } end - def should_show_work_item_type_setting - render_404 unless Gitlab.ee? && ::Feature.enabled?(:work_item_configurable_types, :instance) - end - # overridden in EE def valid_setting_panels VALID_SETTING_PANELS diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 9fe628722fee78..6edba232c43da5 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -185,7 +185,7 @@ put :reset_error_tracking_access_token put :clear_repository_check_states put :reset_vscode_extension_marketplace_extension_host_domain - match :general, :integrations, :repository, :ci_cd, :reporting, :metrics_and_profiling, :network, :preferences, :search, :usage_quotas, :work_item, via: [:get, :patch] + match :general, :integrations, :repository, :ci_cd, :reporting, :metrics_and_profiling, :network, :preferences, :search, :usage_quotas, via: [:get, :patch] get :lets_encrypt_terms_of_service get :slack_app_manifest_download, format: :json get :slack_app_manifest_share diff --git a/ee/app/controllers/ee/admin/application_settings_controller.rb b/ee/app/controllers/ee/admin/application_settings_controller.rb index fc500c7f4124a6..356feb6167d792 100644 --- a/ee/app/controllers/ee/admin/application_settings_controller.rb +++ b/ee/app/controllers/ee/admin/application_settings_controller.rb @@ -21,7 +21,7 @@ module ApplicationSettingsController before_action :indexing_status, only: [:search] before_action :search_error_if_version_incompatible, only: [:search], if: -> { es_helper.ping? } before_action :search_outdated_code_analyzer_detected, only: [:search], if: -> { es_helper.ping? } - before_action :should_show_work_item_type_setting, only: [:work_item] + before_action :check_feature_availability, only: [:work_item] before_action :new_license, only: [:general] before_action :scim_token, only: [:general] @@ -92,7 +92,7 @@ def search_outdated_code_analyzer_detected log_exception(e) end - def should_show_work_item_type_setting + def check_feature_availability render_404 unless ::Feature.enabled?(:work_item_configurable_types, :instance) end @@ -131,7 +131,7 @@ def indexing_status end end - EE_VALID_SETTING_PANELS = %w[search templates security_and_compliance namespace_storage work_item].freeze + EE_VALID_SETTING_PANELS = %w[search templates security_and_compliance namespace_storage].freeze EE_VALID_SETTING_PANELS.each do |action| define_method(action) { perform_update if submitted? } diff --git a/ee/config/routes/admin.rb b/ee/config/routes/admin.rb index 570dc510c86692..0f17b56e772dad 100644 --- a/ee/config/routes/admin.rb +++ b/ee/config/routes/admin.rb @@ -83,7 +83,7 @@ # using `only: []` to keep duplicate routes from being created resource :application_settings, only: [] do get :seat_link_payload - match :templates, :search, :security_and_compliance, :namespace_storage, :analytics, via: [:get, :patch] + match :templates, :search, :security_and_compliance, :namespace_storage, :analytics, :work_item, via: [:get, :patch] get :advanced_search, to: redirect('admin/application_settings/search') get :geo, to: "geo/settings#show" put :update_microsoft_application diff --git a/ee/spec/controllers/admin/application_settings_controller_spec.rb b/ee/spec/controllers/admin/application_settings_controller_spec.rb index 0c211703383fcf..5c511d3f742b21 100644 --- a/ee/spec/controllers/admin/application_settings_controller_spec.rb +++ b/ee/spec/controllers/admin/application_settings_controller_spec.rb @@ -915,6 +915,37 @@ end end + describe 'GET #work_item', feature_category: :team_planning do + before do + sign_in(admin) + end + + context 'when feature flag is disabled' do + before do + stub_feature_flags(work_item_configurable_types: false) + end + + it 'returns 404' do + get :work_item + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when feature flag is enabled' do + before do + stub_feature_flags(work_item_configurable_types: true) + end + + it 'renders the work_item template' do + get :work_item + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to render_template('admin/application_settings/work_item') + end + end + end + def set_maintenance_mode(message) ApplicationSetting.current.update!( maintenance_mode: true, diff --git a/locale/gitlab.pot b/locale/gitlab.pot index d345e0c3328454..492c136e9ce84a 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -77944,6 +77944,9 @@ msgstr "" msgid "WorkItem|Work item not found" msgstr "" +msgid "WorkItem|Work item settings" +msgstr "" + msgid "WorkItem|Work item types" msgstr "" diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb index 10ac65e3b7d041..fdf6a1830da550 100644 --- a/spec/controllers/admin/application_settings_controller_spec.rb +++ b/spec/controllers/admin/application_settings_controller_spec.rb @@ -654,4 +654,34 @@ expect(response).to have_gitlab_http_status(:ok) end end + + describe 'GET #work_item', feature_category: :team_planning do + before do + sign_in(admin) + end + + context 'when feature flag is disabled' do + before do + stub_feature_flags(work_item_configurable_types: false) + end + + it 'returns 404' do + get :work_item + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when feature flag is enabled' do + before do + stub_feature_flags(work_item_configurable_types: true) + end + + it 'returns 404 on CE' do + get :work_item + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end end -- GitLab