diff --git a/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_article_attachments.coffee b/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_article_attachments.coffee index 728cc00fb..743cb38ac 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_article_attachments.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_article_attachments.coffee @@ -16,17 +16,36 @@ class SidebarArticleAttachments extends App.Controller if _.isEmpty(@ticket) || _.isEmpty(@ticket.article_ids) @el.html("
#{App.i18n.translateInline('none')}
") return - html = '' - for ticket_article_id in @ticket.article_ids.sort((a, b) -> b - a) - if App.TicketArticle.exists(ticket_article_id) - article = App.TicketArticle.find(ticket_article_id) - attachments = App.TicketArticle.contentAttachments(article) - if !_.isEmpty(attachments) - html += App.view('ticket_zoom/sidebar_article_attachment')(article: article, attachments: attachments) + + articleIDs = _.clone(@ticket.article_ids) + articleIDs.sort((a, b) -> a - b) + + uniqueAttachments = {} + ticketAttachments = [] + 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.on('click', '.js-attachments img', (e) => @imageView(e) ) + @controllerBind('ui::ticket::load', => + @showObjects(el) + ) imageView: (e) -> e.preventDefault() diff --git a/app/assets/javascripts/app/views/ticket_zoom/sidebar_article_attachment.jst.eco b/app/assets/javascripts/app/views/ticket_zoom/sidebar_article_attachment.jst.eco index b8bf35a33..18927c739 100644 --- a/app/assets/javascripts/app/views/ticket_zoom/sidebar_article_attachment.jst.eco +++ b/app/assets/javascripts/app/views/ticket_zoom/sidebar_article_attachment.jst.eco @@ -1,12 +1,11 @@
-
<%- @humanTime(@article.created_at) %>
- <% for attachment in @article.attachments: %> - <% content_type = @ContentOrMimeType(attachment) %> - download<% end %>> + <% for data in @ticketAttachments: %> + <% content_type = @ContentOrMimeType(data.attachment) %> + download<% end %>>
<% if content_type && @ContentTypeIcon(content_type): %> <% if @canPreview(content_type): %> - + <% else: %> <%- @Icon( @ContentTypeIcon(content_type) ) %> <% end %> @@ -14,8 +13,8 @@ <%- @Icon('file-unknown') %> <% end %>
- <%= attachment.filename %> -
<%- @humanFileSize(attachment.size) %>
+ <%= data.attachment.filename %> +
<%- @humanTime(data.article.created_at) %> (<%- @humanFileSize(data.attachment.size) %>)
<% end %>
diff --git a/app/models/store.rb b/app/models/store.rb index c9f5cef56..0a956ec56 100644 --- a/app/models/store.rb +++ b/app/models/store.rb @@ -216,7 +216,7 @@ returns end def attributes_for_display - slice :id, :filename, :size, :preferences + slice :id, :store_file_id, :filename, :size, :preferences end RESIZABLE_MIME_REGEXP = %r{image/(jpeg|jpg|png)}i.freeze diff --git a/spec/system/ticket/zoom_spec.rb b/spec/system/ticket/zoom_spec.rb index bd5bb44bb..59ae0cff4 100644 --- a/spec/system/ticket/zoom_spec.rb +++ b/spec/system/ticket/zoom_spec.rb @@ -2542,4 +2542,52 @@ RSpec.describe 'Ticket zoom', type: :system do expect(page).to have_text('SOLUTION TIME') 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