Fixes #3930 - Make sidebar attachments unique.

This commit is contained in:
Rolf Schmidt 2022-02-24 12:23:39 +01:00
parent 154b3accf9
commit 92b7c39879
4 changed files with 81 additions and 15 deletions

View file

@ -16,17 +16,36 @@ class SidebarArticleAttachments extends App.Controller
if _.isEmpty(@ticket) || _.isEmpty(@ticket.article_ids) if _.isEmpty(@ticket) || _.isEmpty(@ticket.article_ids)
@el.html("<div>#{App.i18n.translateInline('none')}</div>") @el.html("<div>#{App.i18n.translateInline('none')}</div>")
return return
html = ''
for ticket_article_id in @ticket.article_ids.sort((a, b) -> b - a) articleIDs = _.clone(@ticket.article_ids)
if App.TicketArticle.exists(ticket_article_id) articleIDs.sort((a, b) -> a - b)
article = App.TicketArticle.find(ticket_article_id)
attachments = App.TicketArticle.contentAttachments(article) uniqueAttachments = {}
if !_.isEmpty(attachments) ticketAttachments = []
html += App.view('ticket_zoom/sidebar_article_attachment')(article: article, attachments: attachments) for articleID in articleIDs
continue if !App.TicketArticle.exists(articleID)
article = App.TicketArticle.find(articleID)
attachments = App.TicketArticle.contentAttachments(article)
for attachment in attachments
continue if uniqueAttachments[attachment.store_file_id]
uniqueAttachments[attachment.store_file_id] = true
ticketAttachments.push({ attachment: attachment, article: article })
ticketAttachments = ticketAttachments.reverse()
html = App.view('ticket_zoom/sidebar_article_attachment')(
ticketAttachments: ticketAttachments,
)
@el.html(html) @el.html(html)
@el.on('click', '.js-attachments img', (e) => @el.on('click', '.js-attachments img', (e) =>
@imageView(e) @imageView(e)
) )
@controllerBind('ui::ticket::load', =>
@showObjects(el)
)
imageView: (e) -> imageView: (e) ->
e.preventDefault() e.preventDefault()

View file

@ -1,12 +1,11 @@
<div class="attachments-block js-attachments"> <div class="attachments-block js-attachments">
<div class="attachments-block-headline"><%- @humanTime(@article.created_at) %></div> <% for data in @ticketAttachments: %>
<% for attachment in @article.attachments: %> <% content_type = @ContentOrMimeType(data.attachment) %>
<% content_type = @ContentOrMimeType(attachment) %> <a class="attachment attachment--preview" target="_blank" href="<%= App.Config.get('api_path') %>/ticket_attachment/<%= data.article.ticket_id %>/<%= data.article.id %>/<%= data.attachment.id %>?disposition=attachment" data-type="attachment"<% if @canDownload(content_type): %> download<% end %>>
<a class="attachment attachment--preview" title="<%- content_type %>" target="_blank" href="<%= App.Config.get('api_path') %>/ticket_attachment/<%= @article.ticket_id %>/<%= @article.id %>/<%= attachment.id %>?disposition=attachment" data-type="attachment"<% if @canDownload(content_type): %> download<% end %>>
<div class="attachment-icon"> <div class="attachment-icon">
<% if content_type && @ContentTypeIcon(content_type): %> <% if content_type && @ContentTypeIcon(content_type): %>
<% if @canPreview(content_type): %> <% if @canPreview(content_type): %>
<img src="<%= App.Config.get('api_path') %>/ticket_attachment/<%= @article.ticket_id %>/<%= @article.id %>/<%= attachment.id %>?view=preview"> <img src="<%= App.Config.get('api_path') %>/ticket_attachment/<%= data.article.ticket_id %>/<%= data.article.id %>/<%= data.attachment.id %>?view=preview">
<% else: %> <% else: %>
<%- @Icon( @ContentTypeIcon(content_type) ) %> <%- @Icon( @ContentTypeIcon(content_type) ) %>
<% end %> <% end %>
@ -14,8 +13,8 @@
<%- @Icon('file-unknown') %> <%- @Icon('file-unknown') %>
<% end %> <% end %>
</div> </div>
<span class="attachment-name u-highlight"><%= attachment.filename %></span> <span class="attachment-name u-highlight"><%= data.attachment.filename %></span>
<div class="attachment-size"><%- @humanFileSize(attachment.size) %></div> <div class="attachment-size"><%- @humanTime(data.article.created_at) %> (<%- @humanFileSize(data.attachment.size) %>)</div>
</a> </a>
<% end %> <% end %>
</div> </div>

View file

@ -216,7 +216,7 @@ returns
end end
def attributes_for_display def attributes_for_display
slice :id, :filename, :size, :preferences slice :id, :store_file_id, :filename, :size, :preferences
end end
RESIZABLE_MIME_REGEXP = %r{image/(jpeg|jpg|png)}i.freeze RESIZABLE_MIME_REGEXP = %r{image/(jpeg|jpg|png)}i.freeze

View file

@ -2542,4 +2542,52 @@ RSpec.describe 'Ticket zoom', type: :system do
expect(page).to have_text('SOLUTION TIME') expect(page).to have_text('SOLUTION TIME')
end end
end end
context 'Make sidebar attachments unique #3930', authenticated_as: :authenticate do
let(:ticket) { create(:ticket, group: Group.find_by(name: 'Users')) }
let(:article1) { create(:ticket_article, ticket: ticket) }
let(:article2) { create(:ticket_article, ticket: ticket) }
def attachment_add(article, filename)
Store.add(
object: 'Ticket::Article',
o_id: article.id,
data: "content #{filename}",
filename: filename,
preferences: {
'Content-Type' => 'text/plain',
},
created_by_id: 1,
)
end
def authenticate
attachment_add(article1, 'some_file.txt')
attachment_add(article2, 'some_file.txt')
attachment_add(article2, 'some_file2.txt')
Setting.set('ui_ticket_zoom_sidebar_article_attachments', true)
true
end
before do
visit "#ticket/zoom/#{ticket.id}"
page.find(".tabsSidebar-tabs .tabsSidebar-tab[data-tab='attachment']").click
end
it 'does show the attachment once' do
expect(page).to have_selector('.sidebar-content .attachment.attachment--preview', count: 2)
expect(page).to have_selector('.sidebar-content', text: 'some_file.txt')
expect(page).to have_selector('.sidebar-content', text: 'some_file2.txt')
end
it 'does show up new attachments' do
page.find('.js-textarea').send_keys('new article with attachment')
page.find('input#fileUpload_1', visible: :all).set(Rails.root.join('test/data/mail/mail001.box'))
expect(page).to have_text('mail001.box')
wait.until { Taskbar.find_by(key: "Ticket-#{ticket.id}").attributes_with_association_ids['attachments'].present? }
click '.js-submit'
expect(page).to have_selector('.sidebar-content', text: 'mail001.box')
end
end
end end