diff --git a/app/assets/javascripts/app/controllers/ticket_zoom/article_view.coffee b/app/assets/javascripts/app/controllers/ticket_zoom/article_view.coffee index d70282853..36ac8f621 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom/article_view.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom/article_view.coffee @@ -82,6 +82,7 @@ class ArticleViewItem extends App.ObserverController 'click .textBubble a': 'stopPropagation' 'click .js-toggleFold': 'toggleFold' 'click .richtext-content img': 'imageView' + 'click .attachments img': 'imageView' constructor: -> super @@ -178,9 +179,9 @@ class ArticleViewItem extends App.ObserverController ) return @html App.view('ticket_zoom/article_view')( - ticket: @ticket - article: article - isCustomer: @permissionCheck('ticket.customer') + ticket: @ticket + article: article + isCustomer: @permissionCheck('ticket.customer') ) new App.WidgetAvatar( 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 new file mode 100644 index 000000000..1d3ebe037 --- /dev/null +++ b/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_article_attachments.coffee @@ -0,0 +1,34 @@ +class SidebarArticleAttachments extends App.Controller + sidebarItem: => + return if !@Config.get('ui_ticket_zoom_sidebar_article_attachments') + @item = { + name: 'attachment' + badgeIcon: 'paperclip' + sidebarHead: 'Attachments' + sidebarCallback: @showObjects + sidebarActions: [] + } + @item + + showObjects: (el) => + @el = el + + if !@ticket || _.isEmpty(@ticket.article_ids) + @el.html("
#{App.i18n.translateInline('none')}
") + return + html = '' + for ticket_article_id, index in @ticket.article_ids + article = App.TicketArticle.find(ticket_article_id) + if article && article.attachments && !_.isEmpty(article.attachments) + html = App.view('ticket_zoom/sidebar_article_attachment')(article: article) + html + @el.html(html) + @el.delegate('.js-attachments img', 'click', (e) => + @imageView(e) + ) + + imageView: (e) -> + e.preventDefault() + e.stopPropagation() + new App.TicketZoomArticleImageView(image: $(e.target).get(0).outerHTML) + +App.Config.set('900-ArticleAttachments', SidebarArticleAttachments, 'TicketZoomSidebar') diff --git a/app/assets/javascripts/app/index.coffee b/app/assets/javascripts/app/index.coffee index d9fbb2028..b6fdd1404 100644 --- a/app/assets/javascripts/app/index.coffee +++ b/app/assets/javascripts/app/index.coffee @@ -136,6 +136,43 @@ class App extends Spine.Controller return marked(string) App.i18n.translateContent(string) + ContentTypeIcon: (contentType) -> + icons = + # image + 'image/jpeg': 'file-image' + 'image/jpg': 'file-image' + 'image/png': 'file-image' + 'image/svg': 'file-image' + # documents + 'application/pdf': 'file-pdf' + 'application/msword': 'file-word' # .doc, .dot + 'application/vnd.ms-word': 'file-word' + 'application/vnd.oasis.opendocument.text': 'file-word' + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'file-word' # .docx + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template': 'file-word' # .dotx + 'application/vnd.ms-excel': 'file-excel' # .xls + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'file-excel' # .xlsx + 'application/vnd.oasis.opendocument.spreadsheet': 'file-excel' + 'application/vnd.ms-powerpoint': 'file-powerpoint' # .ppt + 'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'file-powerpoint' # .pptx + 'application/vnd.oasis.opendocument.presentation': 'file-powerpoint' + 'text/plain': 'file-text' + 'text/html': 'file-code' + 'application/json': 'file-code' + 'message/rfc822': 'file-email' + # code + 'application/json': 'file-code' + # text + 'text/plain': 'file-text' + 'text/rtf': 'file-text' + # archives + 'application/gzip': 'file-archive' + 'application/zip': 'file-archive' + return icons[contentType] + + canDownload: (contentType) -> + contentType != 'text/html' + @viewPrint: (object, attributeName, attributes, table) -> if !attributes attributes = {} diff --git a/app/assets/javascripts/app/views/ticket_zoom/article_view.jst.eco b/app/assets/javascripts/app/views/ticket_zoom/article_view.jst.eco index 2f553018d..a425f3913 100644 --- a/app/assets/javascripts/app/views/ticket_zoom/article_view.jst.eco +++ b/app/assets/javascripts/app/views/ticket_zoom/article_view.jst.eco @@ -56,10 +56,27 @@ <%- @Icon('paperclip') %>
<%- @article.attachments.length %> <%- @T('Attached Files') %>
<% for attachment in @article.attachments: %> -
- <%= attachment.filename %> -
<%- @humanFileSize(attachment.size) %>
-
+ <% if !@C('ui_ticket_zoom_attachments_preview'): %> +
+ <%= attachment.filename %> +
+ <% else: %> + download<% end %>> +
+ <% if attachment.preferences && attachment.preferences['Content-Type'] && @ContentTypeIcon(attachment.preferences['Content-Type']): %> + <% if attachment.preferences['Content-Type'].match(/image\/(png|jpg|jpeg)/i): %> + + <% else: %> + <%- @Icon( @ContentTypeIcon(attachment.preferences['Content-Type']) ) %> + <% end %> + <% else: %> + <%- @Icon('file-unknown') %> + <% end %> +
+ <%= attachment.filename %> +
<%- @humanFileSize(attachment.size) %>
+
+ <% end %> <% end %> <% end %> 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 new file mode 100644 index 000000000..a49b2b0f5 --- /dev/null +++ b/app/assets/javascripts/app/views/ticket_zoom/sidebar_article_attachment.jst.eco @@ -0,0 +1,20 @@ +
+
<%- @humanTime(@article.created_at) %>
+ <% for attachment in @article.attachments: %> + download<% end %>> +
+ <% if attachment.preferences && attachment.preferences['Content-Type'] && @ContentTypeIcon(attachment.preferences['Content-Type']): %> + <% if attachment.preferences['Content-Type'].match(/image\/(png|jpg|jpeg)/i): %> + + <% else: %> + <%- @Icon( @ContentTypeIcon(attachment.preferences['Content-Type']) ) %> + <% end %> + <% else: %> + <%- @Icon('file-unknown') %> + <% end %> +
+ <%= attachment.filename %> +
<%- @humanFileSize(attachment.size) %>
+
+ <% end %> +
\ No newline at end of file diff --git a/app/assets/stylesheets/svg-dimensions.css b/app/assets/stylesheets/svg-dimensions.css index 9f063d0e8..df97c6d2b 100644 --- a/app/assets/stylesheets/svg-dimensions.css +++ b/app/assets/stylesheets/svg-dimensions.css @@ -22,6 +22,14 @@ .icon-eyedropper { width: 17px; height: 17px; } .icon-facebook-button { width: 29px; height: 24px; } .icon-facebook { width: 17px; height: 17px; } +.icon-file-archive { width: 24px; height: 31px; } +.icon-file-code { width: 24px; height: 31px; } +.icon-file-email { width: 24px; height: 31px; } +.icon-file-excel { width: 24px; height: 31px; } +.icon-file-pdf { width: 24px; height: 31px; } +.icon-file-powerpoint { width: 24px; height: 31px; } +.icon-file-unknown { width: 24px; height: 31px; } +.icon-file-word { width: 24px; height: 31px; } .icon-form { width: 17px; height: 17px; } .icon-forward { width: 16px; height: 17px; } .icon-full-logo { width: 175px; height: 50px; } diff --git a/app/assets/stylesheets/zammad.scss b/app/assets/stylesheets/zammad.scss index f06160715..09a6dc9e5 100644 --- a/app/assets/stylesheets/zammad.scss +++ b/app/assets/stylesheets/zammad.scss @@ -4957,17 +4957,34 @@ footer { .attachments.attachments--list .attachments-title { font-size: 13px; color: hsl(60,1%,34%); - font-weight: bold; + font-weight: 500; + text-transform: uppercase; padding: 0 7px; - margin: 0 0 4px; } .attachments .icon-paperclip { position: absolute; left: 33px; top: 27px; + fill: hsl(240,1%,84%); } + .attachments-block { + margin-bottom: 12px; + + &:last-child { + margin-bottom: 0; + } + + &-headline { + font-size: 13px; + color: hsl(60,1%,34%); + font-weight: 500; + text-transform: uppercase; + margin: 0 7px; + } + } + .ticket-article-item .task-subline { margin-top: 12px; } @@ -5281,11 +5298,7 @@ footer { border: none; outline: none; resize: none; - } - - .articleNewEdit-body { height: auto; - min-height: 38px; } .article-new .bubble-arrow:after { @@ -5312,28 +5325,53 @@ footer { } .attachment { + display: block; font-size: 13px; padding: 1px 10px 1px 7px; - @include rtl(padding, 1px 7px 1px 10px); - cursor: default; position: relative; - display: flex; + min-height: 42px; + color: inherit; + align-items: center; + border-bottom: 1px solid hsl(0,0%,96%); + + &:last-child { + border-bottom: none; + } } - .attachment:hover { - background: hsl(200,20%,97%); - } + .attachment--preview { + padding: 9px 4px 9px 43px; + } + + .attachment-icon { + position: absolute; + left: 0; + top: 9px; + width: 38px; + text-align: center; + + svg { + vertical-align: bottom; + } + + img { + width: 30px; + height: 30px; + object-fit: cover; + } + } .attachment-name { - @include bidi-style(margin-right, 5px, margin-left, 0); min-width: 0; + display: block; @extend .u-highlight; + word-break: break-all; } .attachment-size { white-space: nowrap; - float: right; - @include bidi-style(margin-right, 10px, margin-left, 0); + font-size: 11px; + color: hsl(200,8%,77%); } .attachment-delete { diff --git a/contrib/icon-sprite.sketch b/contrib/icon-sprite.sketch index 751f95348..0e377212c 100644 Binary files a/contrib/icon-sprite.sketch and b/contrib/icon-sprite.sketch differ diff --git a/db/migrate/20180220000001_setting_attachment_preview.rb b/db/migrate/20180220000001_setting_attachment_preview.rb new file mode 100644 index 000000000..a3ab60ac1 --- /dev/null +++ b/db/migrate/20180220000001_setting_attachment_preview.rb @@ -0,0 +1,61 @@ +class SettingAttachmentPreview < ActiveRecord::Migration[5.1] + def up + + # return if it's a new setup + return if !Setting.find_by(name: 'system_init_done') + Setting.create_if_not_exists( + title: 'Sidebar Attachments', + name: 'ui_ticket_zoom_attachments_preview', + area: 'UI::TicketZoom::Preview', + description: 'Enables preview of attachments.', + options: { + form: [ + { + display: '', + null: true, + name: 'ui_ticket_zoom_attachments_preview', + tag: 'boolean', + translate: true, + options: { + true => 'yes', + false => 'no', + }, + }, + ], + }, + state: false, + preferences: { + prio: 400, + permission: ['admin.ui'], + }, + frontend: true + ) + Setting.create_if_not_exists( + title: 'Sidebar Attachments', + name: 'ui_ticket_zoom_sidebar_article_attachments', + area: 'UI::TicketZoom::Preview', + description: 'Enables a sidebar to show an overview of all attachments.', + options: { + form: [ + { + display: '', + null: true, + name: 'ui_ticket_zoom_sidebar_article_attachments', + tag: 'boolean', + translate: true, + options: { + true => 'yes', + false => 'no', + }, + }, + ], + }, + state: false, + preferences: { + prio: 500, + permission: ['admin.ui'], + }, + frontend: true + ) + end +end diff --git a/db/seeds/settings.rb b/db/seeds/settings.rb index 83ece67d1..e7d504abc 100644 --- a/db/seeds/settings.rb +++ b/db/seeds/settings.rb @@ -698,6 +698,61 @@ Setting.create_if_not_exists( }, frontend: true ) +Setting.create_if_not_exists( + title: 'Sidebar Attachments', + name: 'ui_ticket_zoom_attachments_preview', + area: 'UI::TicketZoom::Preview', + description: 'Enables preview of attachments.', + options: { + form: [ + { + display: '', + null: true, + name: 'ui_ticket_zoom_attachments_preview', + tag: 'boolean', + translate: true, + options: { + true => 'yes', + false => 'no', + }, + }, + ], + }, + state: false, + preferences: { + prio: 400, + permission: ['admin.ui'], + }, + frontend: true +) +Setting.create_if_not_exists( + title: 'Sidebar Attachments', + name: 'ui_ticket_zoom_sidebar_article_attachments', + area: 'UI::TicketZoom::Preview', + description: 'Enables a sidebar to show an overview of all attachments.', + options: { + form: [ + { + display: '', + null: true, + name: 'ui_ticket_zoom_sidebar_article_attachments', + tag: 'boolean', + translate: true, + options: { + true => 'yes', + false => 'no', + }, + }, + ], + }, + state: false, + preferences: { + prio: 500, + permission: ['admin.ui'], + }, + frontend: true +) + Setting.create_if_not_exists( title: 'Set notes for ticket create types.', name: 'ui_ticket_create_notes', diff --git a/public/assets/images/icons.svg b/public/assets/images/icons.svg index 5f9feffe3..987a49cb2 100644 --- a/public/assets/images/icons.svg +++ b/public/assets/images/icons.svg @@ -1,4 +1,6 @@ - + + + arrow-down @@ -137,6 +139,77 @@ facebook + + + file-archive + + + + + + + + + + + + file-code + + + + + + + + file-email + + + + + + + + file-excel + + + + + + + + file-pdf + + + + + + + + file-powerpoint + + + + + + + + + + + file-unknown + + + + + + + + file-word + + + + + form @@ -408,7 +481,7 @@ paperclip - + pen diff --git a/public/assets/images/icons/file-archive.svg b/public/assets/images/icons/file-archive.svg new file mode 100644 index 000000000..d35c5469a --- /dev/null +++ b/public/assets/images/icons/file-archive.svg @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="24px" height="31px" viewBox="0 0 24 31" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch --> + <title>file-archive + Created with Sketch. + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/images/icons/file-code.svg b/public/assets/images/icons/file-code.svg new file mode 100644 index 000000000..85e78669d --- /dev/null +++ b/public/assets/images/icons/file-code.svg @@ -0,0 +1,15 @@ + + + + file-code + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/images/icons/file-email.svg b/public/assets/images/icons/file-email.svg new file mode 100644 index 000000000..cc8653f00 --- /dev/null +++ b/public/assets/images/icons/file-email.svg @@ -0,0 +1,15 @@ + + + + file-email + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/images/icons/file-excel.svg b/public/assets/images/icons/file-excel.svg new file mode 100644 index 000000000..a90ff6c8b --- /dev/null +++ b/public/assets/images/icons/file-excel.svg @@ -0,0 +1,15 @@ + + + + file-excel + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/images/icons/file-pdf.svg b/public/assets/images/icons/file-pdf.svg new file mode 100644 index 000000000..662566c02 --- /dev/null +++ b/public/assets/images/icons/file-pdf.svg @@ -0,0 +1,15 @@ + + + + file-pdf + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/images/icons/file-powerpoint.svg b/public/assets/images/icons/file-powerpoint.svg new file mode 100644 index 000000000..e708ab675 --- /dev/null +++ b/public/assets/images/icons/file-powerpoint.svg @@ -0,0 +1,18 @@ + + + + file-powerpoint + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/images/icons/file-unknown.svg b/public/assets/images/icons/file-unknown.svg new file mode 100644 index 000000000..06ec800c6 --- /dev/null +++ b/public/assets/images/icons/file-unknown.svg @@ -0,0 +1,15 @@ + + + + file-unknown + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/images/icons/file-word.svg b/public/assets/images/icons/file-word.svg new file mode 100644 index 000000000..dfabe8425 --- /dev/null +++ b/public/assets/images/icons/file-word.svg @@ -0,0 +1,15 @@ + + + + file-word + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/images/icons/paperclip.svg b/public/assets/images/icons/paperclip.svg index da109b8f9..4a4b5360a 100644 --- a/public/assets/images/icons/paperclip.svg +++ b/public/assets/images/icons/paperclip.svg @@ -1,12 +1,12 @@ - + paperclip Created with Sketch. - - + + \ No newline at end of file