Browse Source

Adds Watcher list to the list of available query columns for issues (#29894).

Patch by Felix Schäfer (@felix).

git-svn-id: https://svn.redmine.org/redmine/trunk@22793 e93f8b46-1217-0410-a6f0-8f06a7374b81
pull/149/merge
Marius Balteanu 4 weeks ago
parent
commit
61c7d539dc

+ 3
- 2
app/assets/stylesheets/application.css View File

tr.project.closed a, tr.project.archived a { color: #aaa; } tr.project.closed a, tr.project.archived a { color: #aaa; }


tr.issue { text-align: center; white-space: nowrap; } tr.issue { text-align: center; white-space: nowrap; }
tr.issue td.subject, tr.issue td.parent-subject, tr.issue td.category, td.assigned_to, td.last_updated_by, tr.issue td.string, tr.issue td.text, tr.issue td.list, tr.issue td.relations, tr.issue td.parent { white-space: normal; }
tr.issue td.subject, tr.issue td.parent-subject, tr.issue td.category, td.assigned_to, td.last_updated_by, tr.issue td.string, tr.issue td.text, tr.issue td.list, tr.issue td.relations, tr.issue td.parent, tr.issue td.watcher_users { white-space: normal; }
tr.issue td.relations { text-align: left; } tr.issue td.relations { text-align: left; }
tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;} tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
tr.issue td.relations span {white-space: nowrap;}
tr.issue td.relations span, tr.issue td.watcher_users a {white-space: nowrap;}
tr.issue td.watcher_users ul {list-style: none; padding: 0; margin: 0}
table.issues td.block_column {color:#777; font-size:90%; padding:4px 4px 4px 24px; text-align:left; white-space:normal;} table.issues td.block_column {color:#777; font-size:90%; padding:4px 4px 4px 24px; text-align:left; white-space:normal;}
table.issues td.block_column span {font-weight: bold; display: block; margin-bottom: 4px;} table.issues td.block_column span {font-weight: bold; display: block; margin-bottom: 4px;}
table.issues td.block_column pre {white-space:normal;} table.issues td.block_column pre {white-space:normal;}

+ 1
- 1
app/assets/stylesheets/rtl.css View File

tr.project.idnt-8 td.name {padding-left:0; padding-right:11em;} tr.project.idnt-8 td.name {padding-left:0; padding-right:11em;}
tr.project.idnt-9 td.name {padding-left:0; padding-right:12.5em;} tr.project.idnt-9 td.name {padding-left:0; padding-right:12.5em;}


tr.issue td.subject, tr.issue td.relations { text-align:right; }
tr.issue td.subject, tr.issue td.relations, tr.issue td.watcher_users { text-align:right; }
tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;} tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}


table.issues td.description {padding:4px 24px 4px 4px; text-align:right;} table.issues td.description {padding:4px 24px 4px 4px; text-align:right;}

+ 4
- 0
app/helpers/queries_helper.rb View File

link_to_if(value > 0, format_hours(value), project_time_entries_path(item.project, :issue_id => "~#{item.id}")) link_to_if(value > 0, format_hours(value), project_time_entries_path(item.project, :issue_id => "~#{item.id}"))
when :attachments when :attachments
value.to_a.map {|a| format_object(a)}.join(" ").html_safe value.to_a.map {|a| format_object(a)}.join(" ").html_safe
when :watcher_users
content_tag('ul', value.to_a.map {|user| content_tag('li', format_object(user))}.join.html_safe)
else else
format_object(value) format_object(value)
end end
case column.name case column.name
when :attachments when :attachments
value.to_a.map {|a| a.filename}.join("\n") value.to_a.map {|a| a.filename}.join("\n")
when :watcher_users
value.to_a.join("\n")
else else
format_object(value, false) do |value| format_object(value, false) do |value|
case value.class.name case value.class.name

+ 4
- 0
app/models/issue_query.rb View File

QueryColumn.new(:assigned_to, QueryColumn.new(:assigned_to,
:sortable => lambda {User.fields_for_order_statement}, :sortable => lambda {User.fields_for_order_statement},
:groupable => true), :groupable => true),
WatcherQueryColumn.new(:watcher_users, :caption => :label_issue_watchers),
TimestampQueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", TimestampQueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on",
:default_order => 'desc', :groupable => true), :default_order => 'desc', :groupable => true),
QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true), QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true),
if has_custom_field_column? if has_custom_field_column?
scope = scope.preload(:custom_values) scope = scope.preload(:custom_values)
end end
if has_column?(:watcher_users)
scope = scope.preload(:watcher_users)
end


issues = scope.to_a issues = scope.to_a



+ 8
- 0
app/models/query.rb View File

end end
end end


class WatcherQueryColumn < QueryColumn
def value_object(object)
return nil unless User.current.allowed_to?(:"view_#{object.class.name.underscore}_watchers", object.try(:project))

super
end
end

class QueryAssociationColumn < QueryColumn class QueryAssociationColumn < QueryColumn
def initialize(association, attribute, options={}) def initialize(association, attribute, options={})
@association = association @association = association

+ 2
- 0
lib/redmine/export/pdf/issues_pdf_helper.rb View File

value = " " * level + value value = " " * level + value
when :attachments when :attachments
value = value.to_a.map {|a| a.filename}.join("\n") value = value.to_a.map {|a| a.filename}.join("\n")
when :watcher_users
value = value.to_a.join("\n")
end end
if value.is_a?(Date) if value.is_a?(Date)
format_date(value) format_date(value)

+ 61
- 0
test/functional/issues_controller_test.rb View File

assert_include "\"source.rb\npicture.jpg\"", response.body assert_include "\"source.rb\npicture.jpg\"", response.body
end end


def test_index_with_watchers_column
@request.session[:user_id] = 2
get(
:index,
:params => {
:c => %w(subject watcher_users),
:set_filter => '1',
:sort => 'id',
}
)

assert_response :success
assert_select 'td.watcher_users'
assert_select 'tr#issue-2' do
assert_select 'td.watcher_users' do
assert_select 'a[href=?]', '/users/1', :text => User.find(1).name
assert_select 'a[href=?]', '/users/3', :text => User.find(3).name
end
end
end

def test_index_with_watchers_column_only_visible_watchers
@request.session[:user_id] = 3
User.find(3).roles.first.remove_permission! :view_issue_watchers
get(
:index,
:params => {
:c => %w(subject watcher_users),
:set_filter => '1',
:sort => 'id',
}
)

assert_response :success
assert_select 'td.watcher_users'
assert_select 'tr#issue-2' do
assert_select 'td.watcher_users' do
assert_select 'a[href=?]', '/users/1', 0
# Currently not implemented, see https://www.redmine.org/issues/29894#note-17
# You can only know that you are a watcher yourself
# assert_select 'a[href=?]', '/users/3', :text => User.find(3).name
end
end
end

def test_index_with_watchers_column_as_csv
@request.session[:user_id] = 2
get(
:index,
:params => {
:c => %w(subject watcher_users),
:set_filter => '1',
:sort => 'id',
:format => 'csv',
}
)

assert_response :success
assert_include "\"#{User.find(1).name}\n#{User.find(3).name}\"", response.body
end

def test_index_with_estimated_hours_total def test_index_with_estimated_hours_total
Issue.delete_all Issue.delete_all
Issue.generate!(:estimated_hours => '5:30') Issue.generate!(:estimated_hours => '5:30')

Loading…
Cancel
Save