Patch #42938 » adds_subitem_icon.patch
| app/assets/stylesheets/application.css | ||
|---|---|---|
| 388 | 388 |
table.issues td.block_column>span {font-weight: bold; display: block; margin-bottom: 4px;}
|
| 389 | 389 |
table.issues td.block_column>pre {white-space:normal;}
|
| 390 | 390 | |
| 391 |
tr.idnt td.subject, tr.idnt td.name {background: url(/chevron-right-idnt.svg) no-repeat 2px 50%;}
|
|
| 392 |
tr.idnt-1 td.subject, tr.idnt-1 td.name {padding-left: 24px; background-position: 4px 50%;}
|
|
| 393 |
tr.idnt-2 td.subject, tr.idnt-2 td.name {padding-left: 40px; background-position: 20px 50%;}
|
|
| 394 |
tr.idnt-3 td.subject, tr.idnt-3 td.name {padding-left: 56px; background-position: 36px 50%;}
|
|
| 395 |
tr.idnt-4 td.subject, tr.idnt-4 td.name {padding-left: 72px; background-position: 52px 50%;}
|
|
| 396 |
tr.idnt-5 td.subject, tr.idnt-5 td.name {padding-left: 88px; background-position: 68px 50%;}
|
|
| 397 |
tr.idnt-6 td.subject, tr.idnt-6 td.name {padding-left: 104px; background-position: 84px 50%;}
|
|
| 398 |
tr.idnt-7 td.subject, tr.idnt-7 td.name {padding-left: 120px; background-position: 100px 50%;}
|
|
| 399 |
tr.idnt-8 td.subject, tr.idnt-8 td.name {padding-left: 136px; background-position: 116px 50%;}
|
|
| 400 |
tr.idnt-9 td.subject, tr.idnt-9 td.name {padding-left: 152px; background-position: 132px 50%;}
|
|
| 391 |
tr.idnt-1 td.subject, tr.idnt-1 td.name {padding-left: 0;}
|
|
| 392 |
tr.idnt-2 td.subject, tr.idnt-2 td.name {padding-left: 20px;}
|
|
| 393 |
tr.idnt-3 td.subject, tr.idnt-3 td.name {padding-left: 36px;}
|
|
| 394 |
tr.idnt-4 td.subject, tr.idnt-4 td.name {padding-left: 52px;}
|
|
| 395 |
tr.idnt-5 td.subject, tr.idnt-5 td.name {padding-left: 68px;}
|
|
| 396 |
tr.idnt-6 td.subject, tr.idnt-6 td.name {padding-left: 84px;}
|
|
| 397 |
tr.idnt-7 td.subject, tr.idnt-7 td.name {padding-left: 100px;}
|
|
| 398 |
tr.idnt-8 td.subject, tr.idnt-8 td.name {padding-left: 116px;}
|
|
| 399 |
tr.idnt-9 td.subject, tr.idnt-9 td.name {padding-left: 132px;}
|
|
| 401 | 400 | |
| 402 | 401 |
table.issue-report {table-layout:fixed;}
|
| 403 | 402 |
table.issue-report tr.total, table.issue-report-detailed tr.total { font-weight: bold; border-top:2px solid #d0d7de;}
|
| app/helpers/application_helper.rb | ||
|---|---|---|
| 191 | 191 |
h(project.name) |
| 192 | 192 |
else |
| 193 | 193 |
link_to project.name, |
| 194 |
project_url(project, {:only_path => true}.merge(options)),
|
|
| 194 |
# if it is a Struct it comes from ProjectQueriesHelper#project_with_optional_icon |
|
| 195 |
project_url(project.is_a?(Struct) ? project.item : project, {:only_path => true}.merge(options)),
|
|
| 195 | 196 |
html_options |
| 196 | 197 |
end |
| 197 | 198 |
end |
| app/helpers/projects_queries_helper.rb | ||
|---|---|---|
| 24 | 24 |
case column.name |
| 25 | 25 |
when :name |
| 26 | 26 |
link_to_project(item) + |
| 27 |
(tag.span(sprite_icon('user', l(:label_my_projects), icon_only: true), class: 'icon-only icon-user my-project') if User.current.member_of?(item)) +
|
|
| 28 |
(tag.span(sprite_icon('bookmarked', l(:label_my_bookmarks), icon_only: true), class: 'icon-only icon-bookmarked-project') if User.current.bookmarked_project_ids.include?(item.id))
|
|
| 27 |
user_project_icons(item) |
|
| 29 | 28 |
when :short_description |
| 30 | 29 |
if item.description? |
| 31 | 30 |
# Sets :inline_attachments to false to avoid performance issues |
| ... | ... | |
| 56 | 55 |
end |
| 57 | 56 |
end |
| 58 | 57 | |
| 58 |
def column_content_with_subitem_icon(column, item, value, level) |
|
| 59 |
if item.is_a?(Project) |
|
| 60 |
content = |
|
| 61 |
case column.name |
|
| 62 |
when :name |
|
| 63 |
name = (item.child? && level&.positive?) ? sprite_icon('angle-right', item.name) : item.name
|
|
| 64 |
link_to_project(project_with_subitem_icon(item, name)) + |
|
| 65 |
user_project_icons(item) |
|
| 66 |
else |
|
| 67 |
column_value(column, item, value) |
|
| 68 |
end |
|
| 69 | ||
| 70 |
content |
|
| 71 |
end |
|
| 72 |
end |
|
| 73 | ||
| 59 | 74 |
def csv_value(column, object, value) |
| 60 | 75 |
if object.is_a?(Project) |
| 61 | 76 |
case column.name |
| ... | ... | |
| 71 | 86 | |
| 72 | 87 |
private |
| 73 | 88 | |
| 89 |
def user_project_icons(item) |
|
| 90 |
content = + '' |
|
| 91 |
content += tag.span(sprite_icon('user', l(:label_my_projects), icon_only: true), class: 'icon-only icon-user my-project') if User.current.member_of?(item)
|
|
| 92 |
content += tag.span(sprite_icon('bookmarked', l(:label_my_bookmarks), icon_only: true), class: 'icon-only icon-bookmarked-project') if User.current.bookmarked_project_ids.include?(item.id)
|
|
| 93 |
content.html_safe |
|
| 94 |
end |
|
| 95 | ||
| 96 |
# Struct object that behaves like Project#archived? and Project#name |
|
| 97 |
# |
|
| 98 |
# @param item [Project] Instance of a Project |
|
| 99 |
# @param name [String|ActiveSupport::SafeBuffer] If name is not a String |
|
| 100 |
# the object should hold the angle-right icon |
|
| 101 |
# with the subprojects name |
|
| 102 |
# @return [Struct] Object responding to item, name, and archived? |
|
| 103 |
def project_with_subitem_icon(item, name) |
|
| 104 |
Struct.new(:item, :name) do |
|
| 105 |
def archived? |
|
| 106 |
item.archived? |
|
| 107 |
end |
|
| 108 |
end.new(item, name) |
|
| 109 |
end |
|
| 110 | ||
| 74 | 111 |
def get_project_status_label |
| 75 | 112 |
{
|
| 76 | 113 |
Project::STATUS_ACTIVE => l(:project_status_active), |
| app/helpers/queries_helper.rb | ||
|---|---|---|
| 237 | 237 |
content_tag('th', content, :class => column.css_classes)
|
| 238 | 238 |
end |
| 239 | 239 | |
| 240 |
def column_content(column, item) |
|
| 240 |
def column_content(column, item, level = nil)
|
|
| 241 | 241 |
value = column.value_object(item) |
| 242 | 242 |
content = |
| 243 | 243 |
if value.is_a?(Array) |
| 244 | 244 |
values = value.filter_map {|v| column_value(column, item, v)}
|
| 245 | 245 |
safe_join(values, ', ') |
| 246 | 246 |
else |
| 247 |
column_value(column, item, value) |
|
| 247 |
level ? column_content_with_subitem_icon(column, item, value, level) : column_value(column, item, value)
|
|
| 248 | 248 |
end |
| 249 | 249 | |
| 250 | 250 |
call_hook(:helper_queries_column_content, |
| 251 |
{:content => content, :column => column, :item => item})
|
|
| 251 |
{:content => content, :column => column, :item => item, :level =>level})
|
|
| 252 | ||
| 253 |
content |
|
| 254 |
end |
|
| 255 | ||
| 256 |
def column_content_with_subitem_icon(column, item, value, level) |
|
| 257 |
content = |
|
| 258 |
case column.name |
|
| 259 |
when :subject |
|
| 260 |
subject = (item.child? && level&.positive?) ? sprite_icon('angle-right', value) : value
|
|
| 261 |
link_to subject, issue_path(item) |
|
| 262 |
else |
|
| 263 |
column_value(column, item, value) |
|
| 264 |
end |
|
| 265 | ||
| 266 |
call_hook(:helper_queries_column_value, |
|
| 267 |
{:content => content, :column => column, :item => item, :value => value})
|
|
| 252 | 268 | |
| 253 | 269 |
content |
| 254 | 270 |
end |
| app/views/issues/_list.html.erb | ||
|---|---|---|
| 34 | 34 |
<tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
|
| 35 | 35 |
<td class="checkbox hide-when-print"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td>
|
| 36 | 36 |
<% query.inline_columns.each do |column| %> |
| 37 |
<%= content_tag('td', column_content(column, issue), :class => column.css_classes) %>
|
|
| 37 |
<%= content_tag('td', column_content(column, issue, level), :class => column.css_classes) %>
|
|
| 38 | 38 |
<% end %> |
| 39 | 39 |
<td class="buttons"><%= link_to_context_menu %></td> |
| 40 | 40 |
</tr> |
| app/views/projects/_list.html.erb | ||
|---|---|---|
| 49 | 49 |
<% end %> |
| 50 | 50 |
<% end %> |
| 51 | 51 |
<% @query.inline_columns.each do |column| %> |
| 52 |
<%= content_tag('td', column_content(column, entry), :class => column.css_classes) %>
|
|
| 52 |
<%= content_tag('td', column_content(column, entry, level), :class => column.css_classes) %>
|
|
| 53 | 53 |
<% end %> |
| 54 | 54 |
<% if @admin_list %> |
| 55 | 55 |
<% if !entry.scheduled_for_deletion? %> |
| test/helpers/application_helper_test.rb | ||
|---|---|---|
| 22 | 22 |
class ApplicationHelperTest < Redmine::HelperTest |
| 23 | 23 |
include ERB::Util |
| 24 | 24 |
include AvatarsHelper |
| 25 |
include ProjectsQueriesHelper |
|
| 25 | 26 | |
| 26 | 27 |
def setup |
| 27 | 28 |
super |
| ... | ... | |
| 1974 | 1975 |
link_to_project(project, {:only_path => false, :jump => 'blah'})
|
| 1975 | 1976 |
end |
| 1976 | 1977 | |
| 1978 |
def test_link_to_project_with_subitem_icon |
|
| 1979 |
item = Project.find(3) |
|
| 1980 |
level = 1 |
|
| 1981 |
name = (item.child? && level&.positive?) ? sprite_icon('angle-right', item.name) : item.name
|
|
| 1982 |
# requires ProjectsQueriesHelper |
|
| 1983 |
project = project_with_subitem_icon(item, name) |
|
| 1984 |
assert_equal %(<a href=\"/projects/subproject1\"><svg class=\"s18 icon-svg\" aria-hidden=\"true\"><use href=\"/assets/icons-1857f271.svg#icon--angle-right\"></use></svg><span class=\"icon-label\">eCookbook Subproject 1</span></a>), |
|
| 1985 |
link_to_project(project) |
|
| 1986 |
end |
|
| 1987 | ||
| 1977 | 1988 |
def test_link_to_project_settings |
| 1978 | 1989 |
project = Project.find(1) |
| 1979 | 1990 |
assert_equal '<a href="/projects/ecookbook/settings">eCookbook</a>', link_to_project_settings(project) |
| test/helpers/projects_queries_helper_test.rb | ||
|---|---|---|
| 29 | 29 |
assert_equal "active", csv_value(c_status, Project.find(1), 1) |
| 30 | 30 |
assert_equal "eCookbook", csv_value(c_parent_id, Project.find(4), 1) |
| 31 | 31 |
end |
| 32 | ||
| 33 |
def test_column_content_with_subitem_icon |
|
| 34 |
column = QueryColumn.new(:name) |
|
| 35 |
item = Project.find(3) |
|
| 36 |
value = Project.name |
|
| 37 |
level = 1 |
|
| 38 | ||
| 39 |
content = column_content_with_subitem_icon(column, item, value, level) |
|
| 40 |
name_with_subitem_icon = %(<a href=\"/projects/subproject1\"><svg class=\"s18 icon-svg\" aria-hidden=\"true\"><use href=\"/assets/icons-1857f271.svg#icon--angle-right\"></use></svg><span class=\"icon-label\">eCookbook Subproject 1</span></a>) |
|
| 41 |
assert_equal name_with_subitem_icon, content |
|
| 42 |
end |
|
| 32 | 43 |
end |
| test/helpers/queries_helper_test.rb | ||
|---|---|---|
| 109 | 109 |
assert_select_in options, 'option[value=?]', "cf_#{i_cf.id}.cf_#{u_cf.id}", text: "User's Phone number"
|
| 110 | 110 |
assert_select_in options, 'optgroup[label=?]', 'User', 1 |
| 111 | 111 |
end |
| 112 | ||
| 113 |
def test_column_content_should_use_column_content_with_subitem_icon |
|
| 114 |
item = Issue.generate!(parent_id: 2) |
|
| 115 |
column = QueryColumn.new(:subject) |
|
| 116 |
value = item.subject |
|
| 117 |
level = 1 |
|
| 118 |
content = column_content(column, item, level) |
|
| 119 |
assert_equal name_with_subitem_icon(item), content |
|
| 120 |
end |
|
| 121 | ||
| 122 |
private |
|
| 123 | ||
| 124 |
def name_with_subitem_icon(item) |
|
| 125 |
%(<a href=\"/issues/#{item.id}\"><svg class=\"s18 icon-svg\" aria-hidden=\"true\"><use href=\"/assets/icons-1857f271.svg#icon--angle-right\"></use></svg><span class=\"icon-label\">Generated</span></a>)
|
|
| 126 |
end |
|
| 112 | 127 |
end |
- « Previous
- 1
- 2
- 3
- Next »