From c3d7eadd6078762fda9db9ffc64e718738a62755 Mon Sep 17 00:00:00 2001 From: MAEDA Go Date: Sun, 26 Apr 2026 10:40:50 +0900 Subject: [PATCH] Add assignee list display format with groups-first option --- app/helpers/application_helper.rb | 19 ++++++++++++++----- app/helpers/settings_helper.rb | 9 +++++++++ app/views/settings/_issues.html.erb | 4 +++- config/locales/en.yml | 3 +++ config/settings.yml | 2 ++ test/functional/issues_controller_test.rb | 19 +++++++++++++++++++ test/helpers/application_helper_test.rb | 19 +++++++++++++++++++ 7 files changed, 69 insertions(+), 6 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e47fa7f34..a8bedb226 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -699,6 +699,7 @@ module ApplicationHelper users_html = +'' groups_html = +'' collection.sort.each do |element| + selected_attribute = nil if option_value_selected?(element, selected) || element.id.to_s == selected selected_attribute = ' selected="selected"' end @@ -708,11 +709,19 @@ module ApplicationHelper if involved_principals_html.blank? && groups_html.blank? s << users_html else - [ - [l(:label_involved_principals), involved_principals_html], - [l(:label_user_plural), users_html], - [l(:label_group_plural), groups_html] - ].each do |label, options_html| + principal_optgroups = case Setting.principal_display_format.to_s + when 'groups_then_users' + [ + [l(:label_group_plural), groups_html], + [l(:label_user_plural), users_html] + ] + else + [ + [l(:label_user_plural), users_html], + [l(:label_group_plural), groups_html] + ] + end + ([[l(:label_involved_principals), involved_principals_html]] + principal_optgroups).each do |label, options_html| s << %(#{options_html}) if options_html.present? end end diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index 0c0b01fc9..80aef02e6 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -200,6 +200,15 @@ module SettingsHelper options.map {|label, value| [l(label), value.to_s]} end + def principal_display_format_options + options = [ + [:label_principal_display_format_users_then_groups, 'users_then_groups'], + [:label_principal_display_format_groups_then_users, 'groups_then_users'] + ] + + options.map {|label, value| [l(label), value.to_s]} + end + def parent_issue_dates_options options = [ [:label_parent_task_attributes_derived, 'derived'], diff --git a/app/views/settings/_issues.html.erb b/app/views/settings/_issues.html.erb index 3a3a36d1b..05d398a98 100644 --- a/app/views/settings/_issues.html.erb +++ b/app/views/settings/_issues.html.erb @@ -11,7 +11,9 @@

<%= setting_check_box :close_duplicate_issues %>

-

<%= setting_check_box :issue_group_assignment %>

+

<%= setting_check_box :issue_group_assignment, :data => {:enables => '#settings_principal_display_format'} %>

+ +

<%= setting_select :principal_display_format, principal_display_format_options %>

<%= setting_check_box :default_issue_start_date_to_creation_date %>

diff --git a/config/locales/en.yml b/config/locales/en.yml index 8315e12ce..4d59525ac 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -497,6 +497,7 @@ en: setting_gantt_items_limit: Maximum number of items displayed on the gantt chart setting_gantt_months_limit: Maximum number of months displayed on the gantt chart setting_issue_group_assignment: Allow issue assignment to groups + setting_principal_display_format: Assignee list display format setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed setting_unsubscribe: Allow users to delete their own account @@ -1172,6 +1173,8 @@ en: label_edited: Edited label_time_by_author: "%{time} by %{author}" label_involved_principals: Author / Previous assignee + label_principal_display_format_users_then_groups: Users then groups + label_principal_display_format_groups_then_users: Groups then users label_progressbar: Progress bar label_oauth_permission_admin: Administrate this Redmine label_oauth_admin_access: Administration diff --git a/config/settings.yml b/config/settings.yml index 982bc5f1f..304422c90 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -196,6 +196,8 @@ close_duplicate_issues: default: 1 issue_group_assignment: default: 0 +principal_display_format: + default: users_then_groups default_issue_start_date_to_creation_date: default: 0 notified_events: diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb index b553bd411..76e611ca7 100644 --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -4335,6 +4335,25 @@ class IssuesControllerTest < Redmine::ControllerTest assert_equal group, issue.assigned_to end + def test_new_should_render_groups_before_users_in_assignee_select_when_configured + group = Group.find(11) + project = Project.find(1) + project.members << Member.new(:principal => group, :roles => [Role.givable.first]) + + with_settings :issue_group_assignment => '1', :principal_display_format => 'groups_then_users' do + @request.session[:user_id] = 2 + get :new, :params => {:project_id => project.id} + assert_response :success + end + + assert_select 'select[name=?]', 'issue[assigned_to_id]' do + assert_select %(optgroup:nth-of-type(1)[label="#{l(:label_group_plural)}"]) do + assert_select 'option[value=?]', group.id.to_s + end + assert_select %(optgroup:nth-of-type(2)[label="#{l(:label_user_plural)}"]) + end + end + def test_post_create_without_start_date_and_default_start_date_is_not_creation_date with_settings :default_issue_start_date_to_creation_date => 0 do @request.session[:user_id] = 2 diff --git a/test/helpers/application_helper_test.rb b/test/helpers/application_helper_test.rb index 64df5376f..533cac8c3 100644 --- a/test/helpers/application_helper_test.rb +++ b/test/helpers/application_helper_test.rb @@ -1937,6 +1937,25 @@ class ApplicationHelperTest < Redmine::HelperTest end end + def test_principals_options_for_select_with_users_and_groups_with_groups_then_users + User.current = nil + set_language_if_valid 'en' + principals = [User.find(2), Group.find(11), User.find(4), Group.find(10)] + + with_settings :principal_display_format => 'groups_then_users' do + result = principals_options_for_select(principals) + + assert_select_in result, 'optgroup:nth-of-type(1)[label="Groups"]' do + assert_select 'option[value="10"]', text: 'A Team' + assert_select 'option[value="11"]', text: 'B Team' + end + assert_select_in result, 'optgroup:nth-of-type(2)[label="Users"]' do + assert_select 'option[value="2"]', text: 'John Smith' + assert_select 'option[value="4"]', text: 'Robert Hill' + end + end + end + def test_principals_options_for_select_with_empty_collection assert_equal '', principals_options_for_select([]) end -- 2.50.1