選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

custom_fields_helper.rb 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006-2020 Jean-Philippe Lang
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. module CustomFieldsHelper
  19. CUSTOM_FIELDS_TABS = [
  20. {:name => 'IssueCustomField', :partial => 'custom_fields/index',
  21. :label => :label_issue_plural},
  22. {:name => 'TimeEntryCustomField', :partial => 'custom_fields/index',
  23. :label => :label_spent_time},
  24. {:name => 'ProjectCustomField', :partial => 'custom_fields/index',
  25. :label => :label_project_plural},
  26. {:name => 'VersionCustomField', :partial => 'custom_fields/index',
  27. :label => :label_version_plural},
  28. {:name => 'DocumentCustomField', :partial => 'custom_fields/index',
  29. :label => :label_document_plural},
  30. {:name => 'UserCustomField', :partial => 'custom_fields/index',
  31. :label => :label_user_plural},
  32. {:name => 'GroupCustomField', :partial => 'custom_fields/index',
  33. :label => :label_group_plural},
  34. {:name => 'TimeEntryActivityCustomField', :partial => 'custom_fields/index',
  35. :label => TimeEntryActivity::OptionName},
  36. {:name => 'IssuePriorityCustomField', :partial => 'custom_fields/index',
  37. :label => IssuePriority::OptionName},
  38. {:name => 'DocumentCategoryCustomField', :partial => 'custom_fields/index',
  39. :label => DocumentCategory::OptionName}
  40. ]
  41. def render_custom_fields_tabs(types)
  42. tabs = CUSTOM_FIELDS_TABS.select {|h| types.include?(h[:name])}
  43. render_tabs tabs
  44. end
  45. def custom_field_type_options
  46. CUSTOM_FIELDS_TABS.map {|h| [l(h[:label]), h[:name]]}
  47. end
  48. def custom_field_title(custom_field)
  49. items = []
  50. items << [l(:label_custom_field_plural), custom_fields_path]
  51. items << [l(custom_field.type_name), custom_fields_path(:tab => custom_field.class.name)] if custom_field
  52. items << (custom_field.nil? || custom_field.new_record? ? l(:label_custom_field_new) : custom_field.name)
  53. title(*items)
  54. end
  55. def render_custom_field_format_partial(form, custom_field)
  56. partial = custom_field.format.form_partial
  57. if partial
  58. render :partial => custom_field.format.form_partial, :locals => {:f => form, :custom_field => custom_field}
  59. end
  60. end
  61. def custom_field_tag_name(prefix, custom_field)
  62. name = "#{prefix}[custom_field_values][#{custom_field.id}]"
  63. name += "[]" if custom_field.multiple?
  64. name
  65. end
  66. def custom_field_tag_id(prefix, custom_field)
  67. "#{prefix}_custom_field_values_#{custom_field.id}"
  68. end
  69. # Return custom field html tag corresponding to its format
  70. def custom_field_tag(prefix, custom_value)
  71. css = custom_value.custom_field.css_classes
  72. data = nil
  73. if custom_value.custom_field.full_text_formatting?
  74. css += ' wiki-edit'
  75. data = {
  76. :auto_complete => true,
  77. :issues_url => auto_complete_issues_path(:project_id => custom_value.customized.project, :q => '')
  78. } if custom_value.customized&.try(:project)
  79. end
  80. custom_value.custom_field.format.edit_tag(
  81. self,
  82. custom_field_tag_id(prefix, custom_value.custom_field),
  83. custom_field_tag_name(prefix, custom_value.custom_field),
  84. custom_value,
  85. :class => css,
  86. :data => data)
  87. end
  88. # Return custom field name tag
  89. def custom_field_name_tag(custom_field)
  90. title = custom_field.description.presence
  91. css = title ? "field-description" : nil
  92. content_tag 'span', custom_field.name, :title => title, :class => css
  93. end
  94. # Return custom field label tag
  95. def custom_field_label_tag(name, custom_value, options={})
  96. required = options[:required] || custom_value.custom_field.is_required?
  97. for_tag_id = options.fetch(:for_tag_id, "#{name}_custom_field_values_#{custom_value.custom_field.id}")
  98. content = custom_field_name_tag custom_value.custom_field
  99. content_tag(
  100. "label", content +
  101. (required ? " <span class=\"required\">*</span>".html_safe : ""),
  102. :for => for_tag_id)
  103. end
  104. # Return custom field tag with its label tag
  105. def custom_field_tag_with_label(name, custom_value, options={})
  106. tag = custom_field_tag(name, custom_value)
  107. tag_id = nil
  108. ids = tag.scan(/ id="(.+?)"/)
  109. if ids.size == 1
  110. tag_id = ids.first.first
  111. end
  112. custom_field_label_tag(name, custom_value, options.merge(:for_tag_id => tag_id)) + tag
  113. end
  114. # Returns the custom field tag for when bulk editing objects
  115. def custom_field_tag_for_bulk_edit(prefix, custom_field, objects=nil, value='')
  116. css = custom_field.css_classes
  117. data = nil
  118. if custom_field.full_text_formatting?
  119. css += ' wiki-edit'
  120. data = {
  121. :auto_complete => true,
  122. :issues_url => auto_complete_issues_path(:q => '')
  123. }
  124. end
  125. custom_field.format.bulk_edit_tag(
  126. self,
  127. custom_field_tag_id(prefix, custom_field),
  128. custom_field_tag_name(prefix, custom_field),
  129. custom_field,
  130. objects,
  131. value,
  132. :class => css,
  133. :data => data)
  134. end
  135. # Returns custom field value tag
  136. def custom_field_value_tag(value)
  137. attr_value = show_value(value)
  138. if !attr_value.blank? && value.custom_field.full_text_formatting?
  139. content_tag('div', attr_value, :class => 'wiki')
  140. else
  141. attr_value
  142. end
  143. end
  144. # Return a string used to display a custom value
  145. def show_value(custom_value, html=true)
  146. format_object(custom_value, html)
  147. end
  148. # Return a string used to display a custom value
  149. def format_value(value, custom_field)
  150. format_object(custom_field.format.formatted_value(self, custom_field, value, false), false)
  151. end
  152. # Return an array of custom field formats which can be used in select_tag
  153. def custom_field_formats_for_select(custom_field)
  154. Redmine::FieldFormat.as_select(custom_field.class.customized_class.name)
  155. end
  156. # Yields the given block for each custom field value of object that should be
  157. # displayed, with the custom field and the formatted value as arguments
  158. def render_custom_field_values(object, &block)
  159. object.visible_custom_field_values.each do |custom_value|
  160. formatted = show_value(custom_value)
  161. if formatted.present?
  162. yield custom_value.custom_field, formatted
  163. end
  164. end
  165. end
  166. # Renders the custom_values in api views
  167. def render_api_custom_values(custom_values, api)
  168. api.array :custom_fields do
  169. custom_values.each do |custom_value|
  170. attrs = {:id => custom_value.custom_field_id, :name => custom_value.custom_field.name}
  171. attrs[:multiple] = true if custom_value.custom_field.multiple?
  172. api.custom_field attrs do
  173. if custom_value.value.is_a?(Array)
  174. api.array :value do
  175. custom_value.value.each do |value|
  176. api.value value unless value.blank?
  177. end
  178. end
  179. else
  180. api.value custom_value.value
  181. end
  182. end
  183. end
  184. end unless custom_values.empty?
  185. end
  186. def edit_tag_style_tag(form, options={})
  187. select_options = [[l(:label_drop_down_list), ''], [l(:label_checkboxes), 'check_box']]
  188. if options[:include_radio]
  189. select_options << [l(:label_radio_buttons), 'radio']
  190. end
  191. form.select :edit_tag_style, select_options, :label => :label_display
  192. end
  193. def select_type_radio_buttons(default_type)
  194. if CUSTOM_FIELDS_TABS.none? {|tab| tab[:name] == default_type}
  195. default_type = 'IssueCustomField'
  196. end
  197. custom_field_type_options.map do |name, type|
  198. content_tag(:label, :style => 'display:block;') do
  199. radio_button_tag('type', type, type == default_type) + name
  200. end
  201. end.join("\n").html_safe
  202. end
  203. end