Project

General

Profile

Feature #42477 » 0001-Configurable-columns-for-related-and-sub-issues-list.patch

Jens Krämer, 2025-03-25 11:07

View differences:

app/assets/stylesheets/application.css
361 361
table.list table.progress td {padding-right:0px;}
362 362
table.list caption { text-align: left; padding: 0.5em 0.5em 0.5em 0; }
363 363
table.list tr.overdue td.due_date  { color: #c22; }
364
table.list thead.related-issues th { background-color: inherit; font-size: 11px; border: none; }
364 365
#role-permissions-trackers table.list th {white-space:normal;}
365 366

  
366 367
.table-list-cell {display: table-cell; vertical-align: top; padding:2px; }
app/helpers/issues_helper.rb
89 89
    s.html_safe
90 90
  end
91 91

  
92
  def get_related_issues_columns_for_project(issue)
93
    query = IssueQuery.new project: issue.project
94
    available_columns = query.available_inline_columns
95
    column_names = Setting.related_issues_default_columns
96

  
97
    (column_names - %w[tracker subject]).map do |name|
98
      available_columns.find { |f| f.name.to_s == name }
99
    end.compact
100
  end
101

  
92 102
  def render_descendants_tree(issue)
103
    columns_list = get_related_issues_columns_for_project(issue)
104

  
93 105
    manage_relations = User.current.allowed_to?(:manage_subtasks, issue.project)
94 106
    s = +'<table class="list issues odd-even">'
107

  
108
    if Setting.display_related_issues_table_headers?
109
      headers = [l(:field_subject)]
110
      headers += columns_list.map(&:caption)
111
      s << content_tag(:thead, content_tag(:tr, safe_join(headers.map{|h| content_tag :th, h})), class: "related-issues")
112
    end
113

  
95 114
    issue_list(
96 115
      issue.descendants.visible.
97 116
        preload(:status, :priority, :tracker,
......
115 134
          "".html_safe
116 135
        end
117 136
      buttons << link_to_context_menu
118
      s <<
119
        content_tag(
120
          'tr',
121
          content_tag('td', check_box_tag("ids[]", child.id, false, :id => nil),
122
                      :class => 'checkbox') +
123
             content_tag('td',
124
                         link_to_issue(
125
                           child,
126
                           :project => (issue.project_id != child.project_id)),
127
                         :class => 'subject') +
128
             content_tag('td', h(child.status), :class => 'status') +
129
             content_tag('td', link_to_user(child.assigned_to), :class => 'assigned_to') +
130
             content_tag('td', format_date(child.start_date), :class => 'start_date') +
131
             content_tag('td', format_date(child.due_date), :class => 'due_date') +
132
             content_tag('td',
133
                         (if child.disabled_core_fields.include?('done_ratio')
134
                            ''
135
                          else
136
                            progress_bar(child.done_ratio)
137
                          end),
138
                         :class=> 'done_ratio') +
139
             content_tag('td', buttons, :class => 'buttons'),
140
          :class => css)
137

  
138
      row_content =
139
        content_tag('td', check_box_tag('ids[]', child.id, false, id: nil), class: 'checkbox') +
140
        content_tag('td', link_to_issue(child, project: (issue.project_id != child.project_id)), class: 'subject')
141

  
142
      columns_list.each do |column|
143
        row_content << content_tag('td', column_content(column, child), class: column.css_classes.to_s)
144
      end
145

  
146
      row_content << content_tag('td', buttons, class: 'buttons')
147
      s << content_tag('tr', row_content, class: css, id: "issue-#{child.id}").html_safe
141 148
    end
142 149
    s << '</table>'
143 150
    s.html_safe
......
199 206

  
200 207
  # Renders the list of related issues on the issue details view
201 208
  def render_issue_relations(issue, relations)
209
    columns_list = get_related_issues_columns_for_project(issue)
210

  
202 211
    manage_relations = User.current.allowed_to?(:manage_issue_relations, issue.project)
203 212
    s = ''.html_safe
213

  
214
    if Setting.display_related_issues_table_headers?
215
      headers = [l(:field_subject)]
216
      headers += columns_list.map(&:caption)
217
      s = content_tag :thead, content_tag(:tr, safe_join(headers.map{|h| content_tag :th, h})), class: "related-issues"
218
    end
219

  
204 220
    relations.each do |relation|
205 221
      other_issue = relation.other_issue(issue)
206 222
      css = "issue hascontextmenu #{other_issue.css_classes} #{relation.css_classes_for(other_issue)}"
......
219 235
          "".html_safe
220 236
        end
221 237
      buttons << link_to_context_menu
222
      s <<
223
        content_tag(
224
          'tr',
225
          content_tag('td',
226
                      check_box_tag(
227
                        "ids[]", other_issue.id,
228
                        false, :id => nil),
229
                      :class => 'checkbox') +
230
             content_tag('td',
231
                         relation.to_s(@issue) do |other|
232
                           link_to_issue(
233
                             other,
234
                             :project => Setting.cross_project_issue_relations?
235
                           )
236
                         end.html_safe,
237
                         :class => 'subject') +
238
             content_tag('td', other_issue.status, :class => 'status') +
239
             content_tag('td', link_to_user(other_issue.assigned_to), :class => 'assigned_to') +
240
             content_tag('td', format_date(other_issue.start_date), :class => 'start_date') +
241
             content_tag('td', format_date(other_issue.due_date), :class => 'due_date') +
242
             content_tag('td',
243
                         (if other_issue.disabled_core_fields.include?('done_ratio')
244
                            ''
245
                          else
246
                            progress_bar(other_issue.done_ratio)
247
                          end),
248
                         :class=> 'done_ratio') +
249
             content_tag('td', buttons, :class => 'buttons'),
250
          :id => "relation-#{relation.id}",
251
          :class => css)
238

  
239
      subject_content = relation.to_s(@issue) { |other| link_to_issue other, project: Setting.cross_project_issue_relations? }.html_safe
240

  
241
      row_content =
242
        content_tag('td', check_box_tag('ids[]', other_issue.id, false, id: nil), class: 'checkbox') +
243
        content_tag('td', subject_content, class: 'subject')
244

  
245
      columns_list.each do |column|
246
        row_content << content_tag('td', column_content(column, other_issue), class: column.css_classes.to_s)
247
      end
248

  
249
      row_content << content_tag('td', buttons, class: 'buttons')
250
      s << content_tag('tr', row_content, id: "relation-#{relation.id}", class: css)
252 251
    end
253 252
    content_tag('table', s, :class => 'list issues odd-even')
254 253
  end
app/views/settings/_issues.html.erb
62 62
  </p>
63 63
</fieldset>
64 64

  
65
<fieldset class="box">
66
  <legend><%= l(:setting_related_issues_default_columns) %></legend>
67
  <div id="list-definition">
68
    <div>
69
      <%= render_query_columns_selection(
70
            IssueQuery.new(:column_names => Setting.related_issues_default_columns),
71
            :name => 'settings[related_issues_default_columns]') %>
72
      <%= javascript_tag do %>
73
        $('#available_settings_related_issues_default_columns option[value="tracker"]').remove();
74
        $('#available_settings_related_issues_default_columns option[value="subject"]').remove();
75
      <% end %>
76
    </div>
77
  </div>
78

  
79
  <div class="tabular settings">
80
    <p><%= setting_check_box :display_related_issues_table_headers %></p>
81
  </div>
82
</fieldset>
83

  
65 84
<%= submit_tag l(:button_save) %>
66 85
<% end %>
config/locales/de.yml
1059 1059
  setting_user_format: Benutzer-Anzeigeformat
1060 1060
  setting_welcome_text: Willkommenstext
1061 1061
  setting_wiki_compression: Wiki-Historie komprimieren
1062
  setting_related_issues_default_columns: Standard-Spalten für verknüpfte und untergeordnete Aufgaben
1063
  setting_display_related_issues_table_headers: Spaltenüberschriften anzeigen
1062 1064

  
1063 1065
  status_active: aktiv
1064 1066
  status_locked: gesperrt
config/locales/en.yml
522 522
  setting_show_status_changes_in_mail_subject: Show status changes in issue mail notifications subject
523 523
  setting_project_list_defaults: Projects list defaults
524 524
  setting_twofa: Two-factor authentication
525
  setting_related_issues_default_columns: Related and sub issues list defaults
526
  setting_display_related_issues_table_headers: Show table headers
525 527

  
526 528
  permission_add_project: Create project
527 529
  permission_add_subprojects: Create subprojects
config/settings.yml
231 231
issue_list_default_totals:
232 232
  serialized: true
233 233
  default: []
234
related_issues_default_columns:
235
  serialized: true
236
  default:
237
  - status
238
  - assigned_to
239
  - start_date
240
  - due_date
241
  - done_ratio
242
display_related_issues_table_headers:
243
  default: 0
234 244
display_subprojects_issues:
235 245
  default: 1
236 246
time_entry_list_defaults:
test/functional/issues_controller_test.rb
8837 8837
      end
8838 8838
    end
8839 8839
  end
8840

  
8841
  def test_related_issues_columns_setting
8842
    with_settings :related_issues_default_columns => ['status', 'total_estimated_hours'], display_related_issues_table_headers: 1 do
8843
      Issue.find(1).update!(parent_id: 2)
8844
      get :show, params: { id: 2 }
8845
      assert_response :success
8846
      assert_select 'thead.related-issues th', text: 'Subject'
8847
      assert_select 'thead.related-issues th', text: 'Status'
8848
      assert_select 'thead.related-issues th', text: 'Total estimated time'
8849
    end
8850
  end
8840 8851
end
(1-1/2)