mirror of
https://github.com/meineerde/redmine.git
synced 2025-12-20 23:41:12 +00:00
Option for long text custom fields to be displayed under the description field (#21705).
Based on patch by Marius BALTEANU. git-svn-id: http://svn.redmine.org/redmine/trunk@16251 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
8d713ae6ca
commit
b40d66f39f
@ -239,8 +239,8 @@ module IssuesHelper
|
|||||||
r.to_html
|
r.to_html
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_custom_fields_rows(issue)
|
def render_half_width_custom_fields_rows(issue)
|
||||||
values = issue.visible_custom_field_values
|
values = issue.visible_custom_field_values.reject {|value| value.custom_field.full_width_layout?}
|
||||||
return if values.empty?
|
return if values.empty?
|
||||||
half = (values.size / 2.0).ceil
|
half = (values.size / 2.0).ceil
|
||||||
issue_fields_rows do |rows|
|
issue_fields_rows do |rows|
|
||||||
@ -252,6 +252,26 @@ module IssuesHelper
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render_full_width_custom_fields_rows(issue)
|
||||||
|
values = issue.visible_custom_field_values.select {|value| value.custom_field.full_width_layout?}
|
||||||
|
return if values.empty?
|
||||||
|
|
||||||
|
s = ''
|
||||||
|
values.each_with_index do |value, i|
|
||||||
|
if value.custom_field.text_formatting == 'full'
|
||||||
|
attr_value = content_tag('div', show_value(value), class: 'wiki')
|
||||||
|
else
|
||||||
|
attr_value = show_value(value)
|
||||||
|
end
|
||||||
|
content =
|
||||||
|
content_tag('hr') +
|
||||||
|
content_tag('p', content_tag('strong', custom_field_name_tag(value.custom_field) )) +
|
||||||
|
content_tag('div', attr_value, class: 'value')
|
||||||
|
s << content_tag('div', content, class: "cf_#{value.custom_field.id} attribute")
|
||||||
|
end
|
||||||
|
s.html_safe
|
||||||
|
end
|
||||||
|
|
||||||
# Returns the path for updating the issue form
|
# Returns the path for updating the issue form
|
||||||
# with project as the current project
|
# with project as the current project
|
||||||
def update_issue_form_path(project, issue)
|
def update_issue_form_path(project, issue)
|
||||||
|
|||||||
@ -89,7 +89,8 @@ class CustomField < ActiveRecord::Base
|
|||||||
'edit_tag_style',
|
'edit_tag_style',
|
||||||
'user_role',
|
'user_role',
|
||||||
'version_status',
|
'version_status',
|
||||||
'extensions_allowed'
|
'extensions_allowed',
|
||||||
|
'full_width_layout'
|
||||||
|
|
||||||
def format
|
def format
|
||||||
@format ||= Redmine::FieldFormat.find(field_format)
|
@format ||= Redmine::FieldFormat.find(field_format)
|
||||||
@ -186,6 +187,10 @@ class CustomField < ActiveRecord::Base
|
|||||||
format.totalable_supported
|
format.totalable_supported
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def full_width_layout?
|
||||||
|
full_width_layout == '1'
|
||||||
|
end
|
||||||
|
|
||||||
# Returns a ORDER BY clause that can used to sort customized
|
# Returns a ORDER BY clause that can used to sort customized
|
||||||
# objects by their value of the custom field.
|
# objects by their value of the custom field.
|
||||||
# Returns nil if the custom field can not be used for sorting.
|
# Returns nil if the custom field can not be used for sorting.
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
<%= render :partial => 'custom_fields/formats/regexp', :locals => {:f => f, :custom_field => custom_field} %>
|
<%= render :partial => 'custom_fields/formats/regexp', :locals => {:f => f, :custom_field => custom_field} %>
|
||||||
<p><%= f.check_box :text_formatting, {:label => :setting_text_formatting}, 'full', '' %></p>
|
<p><%= f.check_box :text_formatting, {:label => :setting_text_formatting}, 'full', '' %></p>
|
||||||
|
<% if @custom_field.class.name == "IssueCustomField" %>
|
||||||
|
<p><%= f.check_box :full_width_layout %></p>
|
||||||
|
<% end %>
|
||||||
<p><%= f.text_area(:default_value, :rows => 5) %></p>
|
<p><%= f.text_area(:default_value, :rows => 5) %></p>
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
<% custom_field_values = @issue.editable_custom_field_values %>
|
<% custom_field_values = @issue.editable_custom_field_values %>
|
||||||
|
<% custom_field_values_full_width = custom_field_values.select { |value| value.custom_field.full_width_layout? } %>
|
||||||
|
<% custom_field_values -= custom_field_values_full_width %>
|
||||||
|
|
||||||
<% if custom_field_values.present? %>
|
<% if custom_field_values.present? %>
|
||||||
<div class="splitcontent">
|
<div class="splitcontent">
|
||||||
<div class="splitcontentleft">
|
<div class="splitcontentleft">
|
||||||
@ -14,3 +17,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<% custom_field_values_full_width.each do |value| %>
|
||||||
|
<p><%= custom_field_tag_with_label :issue, value, :required => @issue.required_attribute?(value.custom_field_id) %></p>
|
||||||
|
<% end %>
|
||||||
|
|||||||
@ -66,7 +66,7 @@
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end %>
|
end %>
|
||||||
<%= render_custom_fields_rows(@issue) %>
|
<%= render_half_width_custom_fields_rows(@issue) %>
|
||||||
<%= call_hook(:view_issues_show_details_bottom, :issue => @issue) %>
|
<%= call_hook(:view_issues_show_details_bottom, :issue => @issue) %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -87,6 +87,8 @@ end %>
|
|||||||
<%= link_to_attachments @issue, :thumbnails => true %>
|
<%= link_to_attachments @issue, :thumbnails => true %>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|
||||||
|
<%= render_full_width_custom_fields_rows(@issue) %>
|
||||||
|
|
||||||
<%= call_hook(:view_issues_show_description_bottom, :issue => @issue) %>
|
<%= call_hook(:view_issues_show_description_bottom, :issue => @issue) %>
|
||||||
|
|
||||||
<% if !@issue.leaf? || User.current.allowed_to?(:manage_subtasks, @project) %>
|
<% if !@issue.leaf? || User.current.allowed_to?(:manage_subtasks, @project) %>
|
||||||
|
|||||||
@ -372,6 +372,7 @@ en:
|
|||||||
field_textarea_font: Font used for text areas
|
field_textarea_font: Font used for text areas
|
||||||
field_updated_by: Updated by
|
field_updated_by: Updated by
|
||||||
field_last_updated_by: Last updated by
|
field_last_updated_by: Last updated by
|
||||||
|
field_full_width_layout: Full width layout
|
||||||
|
|
||||||
setting_app_title: Application title
|
setting_app_title: Application title
|
||||||
setting_app_subtitle: Application subtitle
|
setting_app_subtitle: Application subtitle
|
||||||
|
|||||||
@ -384,6 +384,7 @@ fr:
|
|||||||
field_textarea_font: Police utilisée pour les champs texte
|
field_textarea_font: Police utilisée pour les champs texte
|
||||||
field_updated_by: Mise à jour par
|
field_updated_by: Mise à jour par
|
||||||
field_last_updated_by: Dernière mise à jour par
|
field_last_updated_by: Dernière mise à jour par
|
||||||
|
field_full_width_layout: Afficher sur toute la largeur
|
||||||
|
|
||||||
setting_app_title: Titre de l'application
|
setting_app_title: Titre de l'application
|
||||||
setting_app_subtitle: Sous-titre de l'application
|
setting_app_subtitle: Sous-titre de l'application
|
||||||
|
|||||||
@ -108,7 +108,7 @@ module Redmine
|
|||||||
CustomField.store_accessor :format_store, *args
|
CustomField.store_accessor :format_store, *args
|
||||||
end
|
end
|
||||||
|
|
||||||
field_attributes :url_pattern
|
field_attributes :url_pattern, :full_width_layout
|
||||||
|
|
||||||
def name
|
def name
|
||||||
self.class.format_name
|
self.class.format_name
|
||||||
|
|||||||
@ -463,8 +463,8 @@ div.issue div.subject h3 {margin: 0; margin-bottom: 0.1em;}
|
|||||||
div.issue span.private, div.journal span.private { position:relative; bottom: 2px; text-transform: uppercase; background: #d22; color: #fff; font-weight:bold; padding: 0px 2px 0px 2px; font-size: 60%; margin-right: 2px; border-radius: 2px;}
|
div.issue span.private, div.journal span.private { position:relative; bottom: 2px; text-transform: uppercase; background: #d22; color: #fff; font-weight:bold; padding: 0px 2px 0px 2px; font-size: 60%; margin-right: 2px; border-radius: 2px;}
|
||||||
div.issue .next-prev-links {color:#999;}
|
div.issue .next-prev-links {color:#999;}
|
||||||
div.issue .attributes {margin-top: 2em;}
|
div.issue .attributes {margin-top: 2em;}
|
||||||
div.issue .attribute {padding-left:180px; clear:left; min-height: 1.8em;}
|
div.issue .attributes .attribute {padding-left:180px; clear:left; min-height: 1.8em;}
|
||||||
div.issue .attribute .label {width: 170px; margin-left:-180px; font-weight:bold; float:left; overflow:hidden; text-overflow: ellipsis;}
|
div.issue .attributes .attribute .label {width: 170px; margin-left:-180px; font-weight:bold; float:left; overflow:hidden; text-overflow: ellipsis;}
|
||||||
div.issue .attribute .value {overflow:hidden; text-overflow: ellipsis;}
|
div.issue .attribute .value {overflow:hidden; text-overflow: ellipsis;}
|
||||||
div.issue.overdue .due-date .value { color: #c22; }
|
div.issue.overdue .due-date .value { color: #c22; }
|
||||||
|
|
||||||
|
|||||||
@ -126,6 +126,20 @@ class CustomFieldsControllerTest < Redmine::ControllerTest
|
|||||||
assert_select '[name=?]', 'custom_field[default_value]', 0
|
assert_select '[name=?]', 'custom_field[default_value]', 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_setting_full_width_layout_shoul_be_present_only_for_long_text_issue_custom_field
|
||||||
|
get :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'text'}
|
||||||
|
assert_response :success
|
||||||
|
assert_select '[name=?]', 'custom_field[full_width_layout]'
|
||||||
|
|
||||||
|
get :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'list'}
|
||||||
|
assert_response :success
|
||||||
|
assert_select '[name=?]', 'custom_field[full_width_layout]', 0
|
||||||
|
|
||||||
|
get :new, :type => 'TimeEntryCustomField', :custom_field => {:field_format => 'text'}
|
||||||
|
assert_response :success
|
||||||
|
assert_select '[name=?]', 'custom_field[full_width_layout]', 0
|
||||||
|
end
|
||||||
|
|
||||||
def test_new_js
|
def test_new_js
|
||||||
xhr :get, :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'list'}, :format => 'js'
|
xhr :get, :new, :type => 'IssueCustomField', :custom_field => {:field_format => 'list'}, :format => 'js'
|
||||||
assert_response :success
|
assert_response :success
|
||||||
|
|||||||
@ -1575,6 +1575,25 @@ class IssuesControllerTest < Redmine::ControllerTest
|
|||||||
assert_select ".cf_1 .value", :text => 'MySQL, Oracle'
|
assert_select ".cf_1 .value", :text => 'MySQL, Oracle'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_show_with_full_width_layout_custom_field_should_show_field_under_description
|
||||||
|
field = IssueCustomField.create!(:name => 'Long text', :field_format => 'text', :full_width_layout => '1',
|
||||||
|
:tracker_ids => [1], :is_for_all => true)
|
||||||
|
issue = Issue.find(1)
|
||||||
|
issue.custom_field_values = {field.id => 'This is a long text'}
|
||||||
|
issue.save!
|
||||||
|
|
||||||
|
get :show, :id => 1
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
# long text custom field should not be render in the attributes div
|
||||||
|
assert_select "div.attributes div.attribute.cf_#{field.id} p strong", 0, :text => 'Long text'
|
||||||
|
assert_select "div.attributes div.attribute.cf_#{field.id} div.value", 0, :text => 'This is a long text'
|
||||||
|
|
||||||
|
# long text custom field should be render under description field
|
||||||
|
assert_select "div.description ~ div.attribute.cf_#{field.id} p strong", :text => 'Long text'
|
||||||
|
assert_select "div.description ~ div.attribute.cf_#{field.id} div.value", :text => 'This is a long text'
|
||||||
|
end
|
||||||
|
|
||||||
def test_show_with_multi_user_custom_field
|
def test_show_with_multi_user_custom_field
|
||||||
field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
|
field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
|
||||||
:tracker_ids => [1], :is_for_all => true)
|
:tracker_ids => [1], :is_for_all => true)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user