Feature #42477 » 0001-Configurable-columns-for-related-and-sub-issues-list.patch
| 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 |