Feature #39530 » group_category_field_plugin_20240118173325.patch
| app/helpers/custom_fields_helper.rb | ||
|---|---|---|
| 227 | 227 |
end |
| 228 | 228 |
end.join("\n").html_safe
|
| 229 | 229 |
end |
| 230 | ||
| 231 |
# Return an array of custom fields for which we want id. |
|
| 232 |
def group_category_layout_for_select(selected_custom_field) |
|
| 233 |
custom_fields=CustomField.all |
|
| 234 |
select='<select name="custom_field[group_category_layout]" id="group_category_layout">' |
|
| 235 |
select+='<option value=""' |
|
| 236 |
if selected_custom_field.group_category_layout == '' |
|
| 237 |
select+=' selected="true"' |
|
| 238 |
end |
|
| 239 |
select+=">None</option>\n" |
|
| 240 |
custom_fields.each do |custom_field| |
|
| 241 |
id_str=String(custom_field.id) |
|
| 242 |
select +='<option value="' + id_str |
|
| 243 |
if id_str == selected_custom_field.group_category_layout |
|
| 244 |
select += '" selected="true' |
|
| 245 |
end |
|
| 246 |
select += '">' + custom_field.name + "</option>\n" |
|
| 247 |
end |
|
| 248 |
select+='</select>' |
|
| 249 |
select.html_safe |
|
| 250 |
end |
|
| 251 | ||
| 252 |
def group_category_layout_custom_field(identifier) |
|
| 253 |
if /\A\d+\z/.match(identifier) |
|
| 254 |
@custom_field = CustomField.find(Integer(identifier)) |
|
| 255 |
end |
|
| 256 |
rescue ActiveRecord::RecordNotFound |
|
| 257 |
nil |
|
| 258 |
end |
|
| 259 | ||
| 260 |
def group_category_layout_display_name(identifier) |
|
| 261 |
@custom_field = group_category_layout_custom_field(identifier) |
|
| 262 |
@custom_field ? @custom_field.name : identifier |
|
| 263 |
end |
|
| 264 | ||
| 265 |
def group_category_layout_description(identifier) |
|
| 266 |
@custom_field = group_category_layout_custom_field(identifier) |
|
| 267 |
title = @custom_field ? @custom_field.description.presence : nil |
|
| 268 |
title ? title : identifier |
|
| 269 |
end |
|
| 270 | ||
| 230 | 271 |
end |
| app/models/custom_field.rb | ||
|---|---|---|
| 100 | 100 |
'user_role', |
| 101 | 101 |
'version_status', |
| 102 | 102 |
'extensions_allowed', |
| 103 |
'full_width_layout') |
|
| 103 |
'full_width_layout', |
|
| 104 |
'group_category_layout') |
|
| 104 | 105 | |
| 105 | 106 |
def copy_from(arg, options={})
|
| 106 | 107 |
return if arg.blank? |
| app/views/custom_fields/_form.html.erb | ||
|---|---|---|
| 7 | 7 |
<p><%= f.text_field :name, :size => 50, :required => true %></p> |
| 8 | 8 |
<p><%= f.text_area :description, :rows => 7 %></p> |
| 9 | 9 | |
| 10 |
<p><label for="group_category_layout"><%= l(:field_group_category_layout) %></label><%= group_category_layout_for_select(@custom_field) %></p> |
|
| 11 | ||
| 10 | 12 |
<% if @custom_field.format.multiple_supported %> |
| 11 | 13 |
<p> |
| 12 | 14 |
<%= f.check_box :multiple %> |
| app/views/custom_fields/index.api.rsb | ||
|---|---|---|
| 15 | 15 |
api.multiple field.multiple? |
| 16 | 16 |
api.default_value field.default_value |
| 17 | 17 |
api.visible field.visible? |
| 18 |
api.group_catgory_layout field.group_category_layout? |
|
| 18 | 19 | |
| 19 | 20 |
values = field.possible_values_options |
| 20 | 21 |
if values.present? |
| app/views/issues/_form_custom_fields.html.erb | ||
|---|---|---|
| 1 | 1 |
<% custom_field_values = @issue.editable_custom_field_values %> |
| 2 | 2 |
<% custom_field_values_full_width = custom_field_values.select { |value| value.custom_field.full_width_layout? } %>
|
| 3 | 3 |
<% custom_field_values -= custom_field_values_full_width %> |
| 4 |
<% custom_field_values_group_category_layout = custom_field_values.select { |value| value.custom_field.group_category_layout? } %>
|
|
| 5 |
<% custom_field_values -= custom_field_values_group_category_layout %> |
|
| 6 |
<% custom_field_values_group_category_layout = custom_field_values_group_category_layout.sort_by { |value| [value.custom_field.group_category_layout] } %>
|
|
| 7 | ||
| 4 | 8 | |
| 5 | 9 |
<% if custom_field_values.present? %> |
| 6 | 10 |
<div class="splitcontent"> |
| ... | ... | |
| 18 | 22 |
</div> |
| 19 | 23 |
<% end %> |
| 20 | 24 | |
| 25 |
<% group_category_layout = '' %> |
|
| 26 | ||
| 27 |
<% custom_field_values_group_category_layout.each do |value| %> |
|
| 28 |
<% if group_category_layout != value.custom_field.group_category_layout -%> |
|
| 29 |
<% if group_category_layout != '' -%> |
|
| 30 |
</fieldset> |
|
| 31 |
<% end -%> |
|
| 32 |
<% group_category_layout = value.custom_field.group_category_layout %> |
|
| 33 |
<fieldset class="group_category_layout" > |
|
| 34 |
<legend> |
|
| 35 |
<span title="<%= group_category_layout_description group_category_layout %>" class="field-description"><%= group_category_layout_display_name group_category_layout %> |
|
| 36 |
</span> |
|
| 37 |
</legend> |
|
| 38 |
<% end -%> |
|
| 39 |
<p><%= custom_field_tag_with_label :issue, value, :required => @issue.required_attribute?(value.custom_field_id) %></p> |
|
| 40 |
<% end %> |
|
| 41 |
</fieldset> |
|
| 42 | ||
| 21 | 43 |
<% custom_field_values_full_width.each do |value| %> |
| 22 | 44 |
<p><%= custom_field_tag_with_label :issue, value, :required => @issue.required_attribute?(value.custom_field_id) %></p> |
| 23 | 45 |
<%= wikitoolbar_for "issue_custom_field_values_#{value.custom_field_id}", preview_issue_path(:project_id => @issue.project, :issue_id => @issue.id) if value.custom_field.full_text_formatting? %>
|
| config/locales/en.yml | ||
|---|---|---|
| 1414 | 1414 |
text_user_destroy_confirmation: "Are you sure you want to delete this user and remove all references to them? This cannot be undone. Often, locking a user instead of deleting them is the better solution. To confirm, please enter their login (%{login}) below."
|
| 1415 | 1415 |
text_project_destroy_enter_identifier: "To confirm, please enter the project's identifier (%{identifier}) below."
|
| 1416 | 1416 |
field_name_or_email_or_login: Name, email or login |
| 1417 |
field_group_category_layout: Group Category Layout |
|
| config/locales/fr.yml | ||
|---|---|---|
| 1468 | 1468 |
text_default_active_job_queue_changed: Gestionnaire de file par défaut le plus adapté |
| 1469 | 1469 |
label_user_mail_option_bookmarked: For any event on my bookmarked projects |
| 1470 | 1470 |
label_option_auto_lang: auto |
| 1471 |
field_group_category_layout: Groupe de présentation |
|
| db/migrate/202311091914_add_custom_fields_group_category_layout.rb | ||
|---|---|---|
| 1 |
class AddCustomFieldsGroupCategoryLayout < ActiveRecord::Migration[6.1] |
|
| 2 |
def up |
|
| 3 |
add_column :custom_fields, :group_category_layout, :text |
|
| 4 |
end |
|
| 5 | ||
| 6 |
def down |
|
| 7 |
remove_column :custom_fields, :group_category_layout |
|
| 8 |
end |
|
| 9 |
end |
|
| 10 | ||
| public/stylesheets/application.css | ||
|---|---|---|
| 568 | 568 |
.wiki-class-ltr {direction:ltr !important;}
|
| 569 | 569 |
.wiki-class-rtl {direction:rtl !important;}
|
| 570 | 570 | |
| 571 |
div.group_category_layout { border-style:solid; border-width:thin; border-color: #ccc}
|
|
| 572 |
fieldset.group_category_layout { border-style:solid; border-width:thin; border-color: #ccc}
|
|
| 573 | ||
| 571 | 574 |
div.issue div.subject div div { padding-left: 16px; word-break: break-word; }
|
| 572 | 575 |
div.issue div.subject p {margin: 0; margin-bottom: 0.1em; font-size: 90%; color: #999;}
|
| 573 | 576 |
div.issue div.subject>div>p { margin-top: 0.5em; }
|
| ... | ... | |
| 582 | 585 |
div.issue .attribute.string_cf .value .wiki p {margin-top: 0; margin-bottom: 0;}
|
| 583 | 586 |
div.issue .attribute.text_cf .value .wiki p:first-of-type {margin-top: 0;}
|
| 584 | 587 |
div.issue.overdue .due-date .value { color: #c22; }
|
| 588 | ||
| 585 | 589 |
body.controller-issues h2.inline-flex {padding-right: 0}
|
| 586 | 590 | |
| 587 | 591 |
#issue_tree table.issues, #relations table.issues { border: 0; }
|