Feature #29894 » 29894v1.patch
| app/assets/stylesheets/application.css | ||
|---|---|---|
| 292 | 292 | 
    tr.project.closed a, tr.project.archived a { color: #aaa; }
   | 
| 293 | 293 | |
| 294 | 294 | 
    tr.issue { text-align: center; white-space: nowrap; }
   | 
| 295 | 
    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; }
   | 
|
| 295 | 
    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; }
   | 
|
| 296 | 296 | 
    tr.issue td.relations { text-align: left; }
   | 
| 297 | 297 | 
    tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
   | 
| 298 | 
    tr.issue td.relations span {white-space: nowrap;}
   | 
|
| 298 | 
    tr.issue td.relations span, tr.issue td.watcher_users a {white-space: nowrap;}
   | 
|
| 299 | 
    tr.issue td.watcher_users ul {list-style: none; padding: 0; margin: 0}
   | 
|
| 299 | 300 | 
    table.issues td.block_column {color:#777; font-size:90%; padding:4px 4px 4px 24px; text-align:left; white-space:normal;}
   | 
| 300 | 301 | 
    table.issues td.block_column span {font-weight: bold; display: block; margin-bottom: 4px;}
   | 
| 301 | 302 | 
    table.issues td.block_column pre {white-space:normal;}
   | 
| app/assets/stylesheets/rtl.css | ||
|---|---|---|
| 61 | 61 | 
    tr.project.idnt-8 td.name {padding-left:0; padding-right:11em;}
   | 
| 62 | 62 | 
    tr.project.idnt-9 td.name {padding-left:0; padding-right:12.5em;}
   | 
| 63 | 63 | |
| 64 | 
    tr.issue td.subject, tr.issue td.relations { text-align:right; }
   | 
|
| 64 | 
    tr.issue td.subject, tr.issue td.relations, tr.issue td.watcher_users { text-align:right; }
   | 
|
| 65 | 65 | 
    tr.issue td.done_ratio table.progress { margin-left:auto; margin-right: auto;}
   | 
| 66 | 66 | |
| 67 | 67 | 
    table.issues td.description {padding:4px 24px 4px 4px; text-align:right;}
   | 
| app/helpers/queries_helper.rb | ||
|---|---|---|
| 277 | 277 | 
            link_to_if(value > 0, format_hours(value), project_time_entries_path(item.project, :issue_id => "~#{item.id}"))
   | 
| 278 | 278 | 
    when :attachments  | 
| 279 | 279 | 
            value.to_a.map {|a| format_object(a)}.join(" ").html_safe
   | 
| 280 | 
    when :watcher_users  | 
|
| 281 | 
            content_tag('ul', value.to_a.map {|user| content_tag('li', format_object(user))}.join.html_safe)
   | 
|
| 280 | 282 | 
    else  | 
| 281 | 283 | 
    format_object(value)  | 
| 282 | 284 | 
    end  | 
| ... | ... | |
| 300 | 302 | 
    case column.name  | 
| 301 | 303 | 
    when :attachments  | 
| 302 | 304 | 
          value.to_a.map {|a| a.filename}.join("\n")
   | 
| 305 | 
    when :watcher_users  | 
|
| 306 | 
          value.to_a.join("\n")
   | 
|
| 303 | 307 | 
    else  | 
| 304 | 308 | 
    format_object(value, false) do |value|  | 
| 305 | 309 | 
    case value.class.name  | 
| app/models/issue_query.rb | ||
|---|---|---|
| 40 | 40 | 
    QueryColumn.new(:assigned_to,  | 
| 41 | 41 | 
                        :sortable => lambda {User.fields_for_order_statement},
   | 
| 42 | 42 | 
    :groupable => true),  | 
| 43 | 
    WatcherQueryColumn.new(:watcher_users, :caption => :label_issue_watchers),  | 
|
| 43 | 44 | 
        TimestampQueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on",
   | 
| 44 | 45 | 
    :default_order => 'desc', :groupable => true),  | 
| 45 | 46 | 
        QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true),
   | 
| ... | ... | |
| 404 | 405 | 
    if has_custom_field_column?  | 
| 405 | 406 | 
    scope = scope.preload(:custom_values)  | 
| 406 | 407 | 
    end  | 
| 408 | 
    if has_column?(:watcher_users)  | 
|
| 409 | 
    scope = scope.preload(:watcher_users)  | 
|
| 410 | 
    end  | 
|
| 407 | 411 | |
| 408 | 412 | 
    issues = scope.to_a  | 
| 409 | 413 | |
| app/models/query.rb | ||
|---|---|---|
| 104 | 104 | 
    end  | 
| 105 | 105 | 
    end  | 
| 106 | 106 | |
| 107 | 
    class WatcherQueryColumn < QueryColumn  | 
|
| 108 | 
    def value_object(object)  | 
|
| 109 | 
        return nil unless User.current.allowed_to?(:"view_#{object.class.name.underscore}_watchers", object.try(:project))
   | 
|
| 110 | ||
| 111 | 
    super  | 
|
| 112 | 
    end  | 
|
| 113 | 
    end  | 
|
| 114 | ||
| 107 | 115 | 
    class QueryAssociationColumn < QueryColumn  | 
| 108 | 116 | 
      def initialize(association, attribute, options={})
   | 
| 109 | 117 | 
    @association = association  | 
| lib/redmine/export/pdf/issues_pdf_helper.rb | ||
|---|---|---|
| 402 | 402 | 
    value = " " * level + value  | 
| 403 | 403 | 
    when :attachments  | 
| 404 | 404 | 
                      value = value.to_a.map {|a| a.filename}.join("\n")
   | 
| 405 | 
    when :watcher_users  | 
|
| 406 | 
                      value = value.to_a.join("\n")
   | 
|
| 405 | 407 | 
    end  | 
| 406 | 408 | 
    if value.is_a?(Date)  | 
| 407 | 409 | 
    format_date(value)  | 
| test/functional/issues_controller_test.rb | ||
|---|---|---|
| 1923 | 1923 | 
    assert_include "\"source.rb\npicture.jpg\"", response.body  | 
| 1924 | 1924 | 
    end  | 
| 1925 | 1925 | |
| 1926 | 
    def test_index_with_watchers_column  | 
|
| 1927 | 
    @request.session[:user_id] = 2  | 
|
| 1928 | 
    get(  | 
|
| 1929 | 
    :index,  | 
|
| 1930 | 
          :params => {
   | 
|
| 1931 | 
    :c => %w(subject watcher_users),  | 
|
| 1932 | 
    :set_filter => '1',  | 
|
| 1933 | 
    :sort => 'id',  | 
|
| 1934 | 
    }  | 
|
| 1935 | 
    )  | 
|
| 1936 | ||
| 1937 | 
    assert_response :success  | 
|
| 1938 | 
    assert_select 'td.watcher_users'  | 
|
| 1939 | 
    assert_select 'tr#issue-2' do  | 
|
| 1940 | 
    assert_select 'td.watcher_users' do  | 
|
| 1941 | 
    assert_select 'a[href=?]', '/users/1', :text => User.find(1).name  | 
|
| 1942 | 
    assert_select 'a[href=?]', '/users/3', :text => User.find(3).name  | 
|
| 1943 | 
    end  | 
|
| 1944 | 
    end  | 
|
| 1945 | 
    end  | 
|
| 1946 | ||
| 1947 | 
    def test_index_with_watchers_column_only_visible_watchers  | 
|
| 1948 | 
    @request.session[:user_id] = 3  | 
|
| 1949 | 
    User.find(3).roles.first.remove_permission! :view_issue_watchers  | 
|
| 1950 | 
    get(  | 
|
| 1951 | 
    :index,  | 
|
| 1952 | 
          :params => {
   | 
|
| 1953 | 
    :c => %w(subject watcher_users),  | 
|
| 1954 | 
    :set_filter => '1',  | 
|
| 1955 | 
    :sort => 'id',  | 
|
| 1956 | 
    }  | 
|
| 1957 | 
    )  | 
|
| 1958 | ||
| 1959 | 
    assert_response :success  | 
|
| 1960 | 
    assert_select 'td.watcher_users'  | 
|
| 1961 | 
    assert_select 'tr#issue-2' do  | 
|
| 1962 | 
    assert_select 'td.watcher_users' do  | 
|
| 1963 | 
    assert_select 'a[href=?]', '/users/1', 0  | 
|
| 1964 | 
    # Currently not implemented, see https://www.redmine.org/issues/29894#note-17  | 
|
| 1965 | 
    # You can only know that you are a watcher yourself  | 
|
| 1966 | 
    # assert_select 'a[href=?]', '/users/3', :text => User.find(3).name  | 
|
| 1967 | 
    end  | 
|
| 1968 | 
    end  | 
|
| 1969 | 
    end  | 
|
| 1970 | ||
| 1971 | 
    def test_index_with_watchers_column_as_csv  | 
|
| 1972 | 
    @request.session[:user_id] = 2  | 
|
| 1973 | 
    get(  | 
|
| 1974 | 
    :index,  | 
|
| 1975 | 
          :params => {
   | 
|
| 1976 | 
    :c => %w(subject watcher_users),  | 
|
| 1977 | 
    :set_filter => '1',  | 
|
| 1978 | 
    :sort => 'id',  | 
|
| 1979 | 
    :format => 'csv',  | 
|
| 1980 | 
    }  | 
|
| 1981 | 
    )  | 
|
| 1982 | ||
| 1983 | 
    assert_response :success  | 
|
| 1984 | 
        assert_include "\"#{User.find(1).name}\n#{User.find(3).name}\"", response.body
   | 
|
| 1985 | 
    end  | 
|
| 1986 | ||
| 1926 | 1987 | 
    def test_index_with_estimated_hours_total  | 
| 1927 | 1988 | 
    Issue.delete_all  | 
| 1928 | 1989 | 
    Issue.generate!(:estimated_hours => '5:30')  |