Fixes #3091 - Enhanced/reworked message header of forwarded mails.
This commit is contained in:
parent
41bba5dda3
commit
1f76712933
3 changed files with 165 additions and 10 deletions
|
@ -148,7 +148,7 @@ class EmailReply extends App.Controller
|
|||
selected = App.Utils.text2html(selected)
|
||||
|
||||
if selected
|
||||
quote_header = @fullQuoteHeader(article)
|
||||
quote_header = @replyQuoteHeader(article)
|
||||
|
||||
selected = "<div><br><br/></div><div><blockquote type=\'cite\'>#{quote_header}#{selected}<br></blockquote></div><div><br></div>"
|
||||
|
||||
|
@ -196,7 +196,7 @@ class EmailReply extends App.Controller
|
|||
body = App.Utils.textCleanup(article.body)
|
||||
body = App.Utils.text2html(body)
|
||||
|
||||
quote_header = @fullQuoteHeader(article)
|
||||
quote_header = App.FullQuoteHeader.fullQuoteHeaderForward(article)
|
||||
|
||||
body = "<br/><div>---Begin forwarded message:---<br/><br/></div><div><blockquote type=\"cite\">#{quote_header}#{body}</blockquote></div><div><br></div>"
|
||||
|
||||
|
@ -339,7 +339,7 @@ class EmailReply extends App.Controller
|
|||
|
||||
true
|
||||
|
||||
@fullQuoteHeader: (article) ->
|
||||
@replyQuoteHeader: (article) ->
|
||||
if !App.Config.get('ui_ticket_zoom_article_email_full_quote_header')
|
||||
return ''
|
||||
|
||||
|
@ -348,4 +348,5 @@ class EmailReply extends App.Controller
|
|||
|
||||
App.i18n.translateInline('On %s, %s wrote:', date, name) + '<br><br>'
|
||||
|
||||
|
||||
App.Config.set('200-EmailReply', EmailReply, 'TicketZoomArticleAction')
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
class App.FullQuoteHeader
|
||||
@fullQuoteHeaderForward: (article) ->
|
||||
if !App.Config.get('ui_ticket_zoom_article_email_full_quote_header')
|
||||
return ''
|
||||
|
||||
output = document.createElement('div')
|
||||
|
||||
data = {
|
||||
Subject: article.subject
|
||||
Date: App.i18n.translateTimestamp(article.created_at)
|
||||
From: @fullQuoteHeaderForwardFrom(article)
|
||||
To: @fullQuoteHeaderForwardTo(article)
|
||||
CC: @fullQuoteHeaderForwardCC(article)
|
||||
}
|
||||
|
||||
for key, value of data
|
||||
if value
|
||||
output.append App.i18n.translateContent(key), ': ', value, document.createElement('br')
|
||||
|
||||
output.append document.createElement('br')
|
||||
|
||||
output.outerHTML
|
||||
|
||||
@fullQuoteHeaderForwardFrom: (article) ->
|
||||
user_id = article.origin_by_id || article.created_by_id
|
||||
|
||||
@fullQuoteHeaderEnsurePrivacy(user_id) || @fullQuoteHeaderEnsurePrivacy(article.from) || article.from
|
||||
|
||||
@fullQuoteHeaderForwardTo: (article) ->
|
||||
if article.type.name is 'email' || article.type.name is 'web'
|
||||
@fullQuoteHeaderEnsurePrivacy(article.to) || article.to
|
||||
else if article.sender.name is 'Customer' && article.type.name is 'phone'
|
||||
if email_address_id = App.Group.findByAttribute('name', article.to)?.email_address_id
|
||||
App.EmailAddress.find(email_address_id).displayName()
|
||||
else
|
||||
article.to
|
||||
else if article.sender.name is 'Agent' && article.type.name is 'phone'
|
||||
ticket = App.Ticket.find article.ticket_id
|
||||
@fullQuoteHeaderEnsurePrivacy(ticket.customer_id) || @fullQuoteHeaderEnsurePrivacy(article.to) || article.to
|
||||
else
|
||||
article.to
|
||||
|
||||
@fullQuoteHeaderForwardCC: (article) ->
|
||||
return if !article.cc
|
||||
|
||||
article
|
||||
.cc
|
||||
.split(',')
|
||||
.map (elem) ->
|
||||
elem.trim()
|
||||
.map (elem) =>
|
||||
@fullQuoteHeaderEnsurePrivacy(elem) || elem
|
||||
.join(', ')
|
||||
|
||||
@fullQuoteHeaderEnsurePrivacyParseInput: (input) ->
|
||||
switch typeof input
|
||||
when 'number'
|
||||
App.User.find input
|
||||
when 'string'
|
||||
if email = @fullQuoteHeaderExtractEmail(input)
|
||||
App.User.findByAttribute('email', email)
|
||||
when 'object'
|
||||
input
|
||||
|
||||
@fullQuoteHeaderEnsurePrivacy: (input) =>
|
||||
user = @fullQuoteHeaderEnsurePrivacyParseInput(input)
|
||||
|
||||
return if !user
|
||||
|
||||
output = "#{user.displayName()}"
|
||||
|
||||
if !user.permission('ticket.agent') && user.email
|
||||
output += " <#{user.email}>"
|
||||
|
||||
output
|
||||
|
||||
@fullQuoteHeaderExtractEmail: (input) ->
|
||||
if match = input.match(/<?(\S+@\S[^>]+)(>?)/)
|
||||
match[1]
|
|
@ -23,7 +23,7 @@ RSpec.describe 'Ticket > Update > Full Quote Header', type: :system, time_zone:
|
|||
click_forward
|
||||
|
||||
within(:richtext) do
|
||||
expect(page).to contain_full_quote(ticket_article)
|
||||
expect(page).to contain_full_quote(ticket_article).formatted_for(:forward)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -33,7 +33,21 @@ RSpec.describe 'Ticket > Update > Full Quote Header', type: :system, time_zone:
|
|||
highlight_and_click_reply
|
||||
|
||||
within(:richtext) do
|
||||
expect(page).to contain_full_quote(ticket_article)
|
||||
expect(page).to contain_full_quote(ticket_article).formatted_for(:reply)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when customer is agent' do
|
||||
let(:customer) { create(:agent) }
|
||||
|
||||
it 'includes OP without email when forwarding' do
|
||||
within(:active_content) do
|
||||
click_forward
|
||||
|
||||
within(:richtext) do
|
||||
expect(page).to contain_full_quote(ticket_article).formatted_for(:forward).ensuring_privacy(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -47,7 +61,7 @@ RSpec.describe 'Ticket > Update > Full Quote Header', type: :system, time_zone:
|
|||
click_forward
|
||||
|
||||
within(:richtext) do
|
||||
expect(page).not_to contain_full_quote(ticket_article)
|
||||
expect(page).not_to contain_full_quote(ticket_article).formatted_for(:forward)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -57,7 +71,7 @@ RSpec.describe 'Ticket > Update > Full Quote Header', type: :system, time_zone:
|
|||
highlight_and_click_reply
|
||||
|
||||
within(:richtext) do
|
||||
expect(page).not_to contain_full_quote(ticket_article)
|
||||
expect(page).not_to contain_full_quote(ticket_article).formatted_for(:reply)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -82,11 +96,65 @@ RSpec.describe 'Ticket > Update > Full Quote Header', type: :system, time_zone:
|
|||
|
||||
define :contain_full_quote do
|
||||
match do
|
||||
citation.has_text?(name) && citation.has_no_text?(email) && citation.has_text?(timestamp)
|
||||
confirm_content && confirm_style
|
||||
end
|
||||
|
||||
match_when_negated do
|
||||
citation.has_no_text?(name) && citation.has_no_text?(email) && citation.has_no_text?(timestamp)
|
||||
confirm_no_content
|
||||
end
|
||||
|
||||
# sets expected quote format
|
||||
# @param [Symbol] :forward or :reply, defaults to :reply if not set
|
||||
chain :formatted_for do |style|
|
||||
@style = style
|
||||
end
|
||||
|
||||
def style
|
||||
@style || :reply # rubocop:disable RSpec/InstanceVariable
|
||||
end
|
||||
|
||||
# sets expected privacy level
|
||||
# @param [Boolean] defaults to false if not set
|
||||
chain :ensuring_privacy do |flag|
|
||||
@ensuring_privacy = flag
|
||||
end
|
||||
|
||||
def ensure_privacy?
|
||||
@ensuring_privacy || false # rubocop:disable RSpec/InstanceVariable
|
||||
end
|
||||
|
||||
def confirm_content
|
||||
case style
|
||||
when :reply
|
||||
confirm_content_reply
|
||||
when :forward
|
||||
confirm_content_forward
|
||||
end
|
||||
end
|
||||
|
||||
def confirm_content_reply
|
||||
citation.has_text?(name) && citation.has_no_text?(email) && citation.has_text?(timestamp_reply)
|
||||
end
|
||||
|
||||
def confirm_content_forward
|
||||
if ensure_privacy?
|
||||
citation.has_text?(name) && citation.has_no_text?(email) && citation.has_text?(timestamp_forward)
|
||||
else
|
||||
citation.has_text?(name) && citation.has_text?(email) && citation.has_text?(timestamp_forward)
|
||||
end
|
||||
end
|
||||
|
||||
def confirm_no_content
|
||||
citation.has_no_text?(name) && citation.has_no_text?(email) && citation.has_no_text?(timestamp_reply) && citation.has_no_text?(timestamp_forward)
|
||||
end
|
||||
|
||||
def confirm_style
|
||||
case style
|
||||
when :forward
|
||||
citation.text.match?(/Subject(.+)\nDate(.+)/)
|
||||
when :reply
|
||||
citation.text.match?(/^On(.+)wrote:$/)
|
||||
end
|
||||
end
|
||||
|
||||
def citation
|
||||
|
@ -101,11 +169,18 @@ RSpec.describe 'Ticket > Update > Full Quote Header', type: :system, time_zone:
|
|||
expected.created_by.email
|
||||
end
|
||||
|
||||
def timestamp
|
||||
def timestamp_reply
|
||||
expected
|
||||
.created_at
|
||||
.in_time_zone('Europe/London')
|
||||
.strftime('%A, %B %1d, %Y, %1I:%M:%S %p')
|
||||
end
|
||||
|
||||
def timestamp_forward
|
||||
expected
|
||||
.created_at
|
||||
.in_time_zone('Europe/London')
|
||||
.strftime('%m/%d/%Y %H:%M')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue