UX: display text & html parts alongside raw email in incoming email modal

This commit is contained in:
Régis Hanol 2017-03-08 23:15:42 +01:00
parent dfd5b06c82
commit 00380d84c5
7 changed files with 144 additions and 19 deletions

View File

@ -5,15 +5,39 @@ import IncomingEmail from 'admin/models/incoming-email';
// This controller handles displaying of raw email
export default Ember.Controller.extend(ModalFunctionality, {
rawEmail: "",
textPart: "",
htmlPart: "",
tab: "raw",
showRawEmail: Ember.computed.equal("tab", "raw"),
showTextPart: Ember.computed.equal("tab", "text_part"),
showHtmlPart: Ember.computed.equal("tab", "html_part"),
onShow() { this.send("displayRaw"); },
loadRawEmail(postId) {
return Post.loadRawEmail(postId)
.then(result => this.set("rawEmail", result.raw_email));
.then(result => this.setProperties({
"rawEmail": result.raw_email,
"textPart": result.text_part,
"htmlPart": result.html_part,
}));
},
loadIncomingRawEmail(incomingEmailId) {
return IncomingEmail.loadRawEmail(incomingEmailId)
.then(result => this.set("rawEmail", result.raw_email));
.then(result => this.setProperties({
"rawEmail": result.raw_email,
"textPart": result.text_part,
"htmlPart": result.html_part,
}));
},
actions: {
displayRaw() { this.set("tab", "raw"); },
displayTextPart() { this.set("tab", "text_part"); },
displayHtmlPart() { this.set("tab", "html_part"); }
}
});

View File

@ -1,7 +1,45 @@
{{#d-modal-body title="raw_email.title" maxHeight="80%"}}
{{#if rawEmail}}
{{textarea value=rawEmail class="raw-email-textarea"}}
{{else}}
{{i18n 'raw_email.not_available'}}
{{/if}}
{{#d-modal-body title="raw_email.title" class="incoming-email-modal" maxHeight="80%"}}
<div class="incoming-email-tabs">
{{d-button action="displayRaw"
label="post.raw_email.displays.raw.button"
title="post.raw_email.displays.raw.title"
class=(if showRawEmail 'active')
}}
{{#if textPart}}
{{d-button action="displayTextPart"
label="post.raw_email.displays.text_part.button"
title="post.raw_email.displays.text_part.title"
class=(if showTextPart 'active')
}}
{{/if}}
{{#if htmlPart}}
{{d-button action="displayHtmlPart"
label="post.raw_email.displays.html_part.button"
title="post.raw_email.displays.html_part.title"
class=(if showHtmlPart 'active')
}}
{{/if}}
</div>
<div class="incoming-email-content">
{{#if showRawEmail}}
{{#if rawEmail}}
{{textarea value=rawEmail}}
{{else}}
{{i18n 'raw_email.not_available'}}
{{/if}}
{{/if}}
{{#if showTextPart}}
{{textarea value=textPart}}
{{/if}}
{{#if showHtmlPart}}
<div class="incoming-email-html-part">
{{{htmlPart}}}
</div>
{{/if}}
</div>
{{/d-modal-body}}

View File

@ -73,9 +73,6 @@
max-width: 710px;
margin: 0 auto;
background-color: $secondary;
border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
box-shadow: 0 3px 7px rgba(0,0,0, .8);
background-clip: padding-box;
}
@ -154,9 +151,6 @@
.warning {
color: $danger !important;
}
.raw-email-textarea {
height: 300px;
}
.json-uploader {
.jsfu-shade-container {
display: table-row;
@ -330,3 +324,41 @@
}
}
.incoming-email-modal {
.btn {
transition: none;
background-color: transparent;
margin-right: 5px;
&:hover, &.active {
color: $primary;
}
&.active {
font-weight: bold;
}
&:focus {
outline: 2px solid dark-light-diff($primary, $secondary, 90%, -60%);
}
}
.incoming-email-tabs {
margin-bottom: 15px;
}
.incoming-email-content {
height: 300px;
textarea, .incoming-email-html-part {
height: 95%;
border: none;
border-top: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
padding-top: 10px;
}
textarea {
font-family: monospace;
resize: none;
border-radius: 0px;
box-shadow: none;
}
.incoming-email-html-part {
padding: 10px 4px 4px 4px;
}
}
}

View File

@ -78,7 +78,8 @@ class Admin::EmailController < Admin::AdminController
def raw_email
params.require(:id)
incoming_email = IncomingEmail.find(params[:id].to_i)
render json: { raw_email: incoming_email.raw }
text, html = Email.extract_parts(incoming_email.raw)
render json: { raw_email: incoming_email.raw, text_part: text, html_part: html }
end
def incoming

View File

@ -109,14 +109,15 @@ class PostsController < ApplicationController
end
def cooked
post = find_post_from_params
render json: {cooked: post.cooked}
render json: { cooked: find_post_from_params.cooked }
end
def raw_email
params.require(:id)
post = Post.unscoped.find(params[:id].to_i)
guardian.ensure_can_view_raw_email!(post)
render json: { raw_email: post.raw_email }
text, html = Email.extract_parts(post.raw_email)
render json: { raw_email: post.raw_email, text_part: text, html_part: html }
end
def short_link

View File

@ -1918,6 +1918,18 @@ en:
title: "Show the raw source diffs side-by-side"
button: 'Raw'
raw_email:
displays:
raw:
title: "Show the raw email"
button: 'Raw'
text_part:
title: "Show the text part of the email"
button: 'Text'
html_part:
title: "Show the html part of the email"
button: 'HTML'
category:
can: 'can&hellip; '
none: '(no category)'
@ -2123,7 +2135,7 @@ en:
changed_by: "by {{author}}"
raw_email:
title: "Raw Email"
title: "Incoming Email"
not_available: "Not available!"
categories_list: "Categories List"

View File

@ -29,4 +29,21 @@ module Email
name ? name.gsub(/[:<>,"]/, '') : name
end
def self.extract_parts(raw)
mail = Mail.new(raw)
text = nil
html = nil
if mail.multipart?
text = mail.text_part
html = mail.html_part
elsif mail.content_type.to_s["text/html"]
html = mail
else
text = mail
end
[text&.decoded, html&.decoded]
end
end