Project

General

Profile

Feature #44552 » 0001-Add-a-link-from-each-issue-attachment-to-the-note-in.patch

Go MAEDA, 2026-09-28 16:21

View differences:

app/assets/images/icons.svg
136 136
    <symbol viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" id="icon--checked">
137 137
      <path d="M5 12l5 5l10 -10"/>
138 138
    </symbol>
139
    <symbol viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" id="icon--chevrons-down">
140
      <path d="M7 7l5 5l5 -5"/>
141
      <path d="M7 13l5 5l5 -5"/>
142
    </symbol>
139 143
    <symbol viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" id="icon--chevrons-left">
140 144
      <path d="M11 7l-5 5l5 5"/>
141 145
      <path d="M17 7l-5 5l5 5"/>
app/assets/stylesheets/application.css
1454 1454
div.attachments img { vertical-align: middle; }
1455 1455
div.attachments span.author { font-size: 0.9em; color: var(--oc-gray-6); }
1456
div.attachments span.attachment-journal { display: inline-flex; inline-size: 18px; block-size: 18px; vertical-align: text-bottom; }
1456 1457
div.thumbnails {margin:0.6em;}
1457 1458
div.thumbnail {
app/helpers/attachments_helper.rb
34 34
  # Options:
35 35
  #   :author -- author names are not displayed if set to false
36 36
  #   :thumbails -- display thumbnails if enabled in settings
37
  #   :journals -- hash of journals keyed by attachment id, used to display
38
  #                a link to the journal that added each attachment
37 39
  def link_to_attachments(container, options = {})
38
    options.assert_valid_keys(:author, :thumbnails)
40
    options.assert_valid_keys(:author, :thumbnails, :journals)
39 41
    attachments =
40 42
      if container.attachments.loaded?
41 43
        container.attachments
app/helpers/issues_helper.rb
691 691
    end
692 692
  end
693
  # Returns a hash of the journals that added an attachment,
694
  # keyed by attachment id
695
  def journals_by_attachment_id(journals)
696
    journals.to_a.each_with_object({}) do |journal, h|
697
      journal.details.each do |detail|
698
        next unless detail.property == 'attachment' && detail.value.present?
699

  
700
        h[detail.prop_key.to_i] = journal
701
      end
702
    end
703
  end
704

  
693 705
  # Issue history tabs
694 706
  def issue_history_tabs
695 707
    tabs = []
app/views/attachments/_links.html.erb
21 21
  </td>
22 22
  <td><%= attachment.description unless attachment.description.blank? %></td>
23 23
  <td>
24
    <% if options[:journals].present? %>
25
      <span class="attachment-journal">
26
        <% if journal = options[:journals][attachment.id] %>
27
          <% anchor = "#note-#{journal.indice}" %>
28
          <%= link_to sprite_icon('chevrons-down', anchor), anchor,
29
                      :title => anchor,
30
                      :class => 'icon-only icon-chevrons-down' %>
31
        <% end %>
32
      </span>
33
    <% end %>
24 34
    <% if options[:author] %>
25 35
      <span class="author"><%= attachment.author %>, <%= format_time(attachment.created_on) %></span>
26 36
    <% end %>
app/views/issues/show.html.erb
123 123
<% if @issue.attachments.any? %>
124 124
  <hr />
125 125
  <p><strong><%=l(:label_attachment_plural)%></strong></p>
126
  <%= link_to_attachments @issue, :thumbnails => true %>
126
  <%= link_to_attachments @issue, :thumbnails => true, :journals => journals_by_attachment_id(@journals) %>
127 127
<% end %>
128 128
<%= render_full_width_custom_fields_rows(@issue) %>
config/icon_source.yml
199 199
  svg: chevrons-right
200 200
- name: chevrons-left
201 201
  svg: chevrons-left
202
- name: chevrons-down
203
  svg: chevrons-down
202 204
- name: key
203 205
  svg: key
204 206
- name: search
test/functional/issues_controller_test.rb
2319 2319
    assert_select 'div#relations div.contextual a.icon.icon-link-add', :text => /Add/
2320 2320
  end
2321
  def test_show_should_link_attachments_to_the_journal_that_added_them
2322
    @request.session[:user_id] = 2
2323
    get(:show, :params => {:id => 2})
2324

  
2325
    assert_response :success
2326
    # Attachment 4 was added by journal 3, which is the first journal of the issue
2327
    assert_select 'div.attachments a.icon-attachment[href=?]', '/attachments/4'
2328
    assert_select 'div.attachments span.attachment-journal a', 1
2329
    assert_select 'div.attachments span.attachment-journal a[href=?][title=?]', '#note-1', '#note-1' do
2330
      assert_select "svg.icon-svg use:match('href', ?)", /assets\/icons-\w+.svg#icon--chevrons-down/
2331
    end
2332
  end
2333

  
2334
  def test_show_should_not_link_attachments_to_invisible_private_notes
2335
    journal = Journal.find(3)
2336
    journal.update_columns(:private_notes => true, :user_id => 1)
2337
    @request.session[:user_id] = 2
2338

  
2339
    get(:show, :params => {:id => 2})
2340
    assert_response :success
2341
    assert_select 'div.attachments span.attachment-journal a[href=?]', '#note-1'
2342

  
2343
    Role.find(1).remove_permission! :view_private_notes
2344
    get(:show, :params => {:id => 2})
2345
    assert_response :success
2346
    assert_select 'div.attachments a.icon-attachment[href=?]', '/attachments/4'
2347
    assert_select 'div.attachments span.attachment-journal', 0
2348
  end
2349

  
2321 2350
  def test_show_should_display_attachment_icons_by_mime_type
2322 2351
    @request.session[:user_id] = 2
2323 2352
    get(:show, :params => {:id => 3})
test/helpers/issues_helper_test.rb
456 456
    assert_include "<a href=\"/issues?issue_id=#{open_issue.id}%2C#{closed_issue.id}&amp;set_filter=true&amp;status_id=o\">1 open</a>", html
457 457
    assert_include "<a href=\"/issues?issue_id=#{open_issue.id}%2C#{closed_issue.id}&amp;set_filter=true&amp;status_id=c\">1 closed</a>", html
458 458
  end
459

  
460
  def test_journals_by_attachment_id
461
    issue = Issue.find(2)
462
    # Detail of a removed attachment
463
    JournalDetail.create!(:journal => issue.journals.last, :property => 'attachment',
464
                          :prop_key => '99', :old_value => 'removed.txt')
465
    journals = issue.visible_journals_with_index(User.find(2))
466

  
467
    result = journals_by_attachment_id(journals)
468

  
469
    assert_equal [4], result.keys
470
    assert_equal 3, result[4].id
471
    assert_equal 1, result[4].indice
472
  end
459 473
end
(2-2/2)