Slack attachment in email notifications (#20946)

* First POC

* Added author data and markdown support

* WIP

* styled fields

* WIP

* WIP

* IMplementation done

* Updated template

* fixed mjml compilation error

* removed card.mjml

* Added test

* Updated a styling

* Updated a styling

* CI

* Updated generated templates

* Explicitelly specified font for message attachments

* Lint fix

* Removed leftover existances of slack attachment
Этот коммит содержится в:
Harshil Sharma
2022-10-20 11:05:22 +05:30
коммит произвёл GitHub
родитель 312bf283a8
Коммит 31e6cdd0e6
12 изменённых файлов: 729 добавлений и 45 удалений

Просмотреть файл

@@ -8,7 +8,13 @@
<mj-include path="./partials/header.mjml" />
<mj-raw>{{if .Props.Message}}</mj-raw>
<mj-raw>{{range .Props.Posts}}<div class="postCard"></mj-raw>
<mj-include path="./partials/card.mjml" />
<mj-section css-class="messageCard" padding="0px">
<mj-group>
<mj-include path="./partials/message_avatar_col.mjml" />
<mj-include path="./partials/sender_info_col.mjml" />
<mj-include path="./partials/message_button.mjml" />
</mj-group>
</mj-section>
<mj-raw></div>{{end}}</mj-raw>
<mj-raw>{{else}}</mj-raw>
<mj-section padding="0px 0px 40px 0px">

Просмотреть файл

@@ -356,7 +356,160 @@
max-width: 100% !important;
}
}
.messageAttachments * {
font-family: Open Sans, sans-serif !important;
}
.messageAttachmentContent {
padding: 0px;
border: 1px solid rgba(63, 67, 80, 0.16);
margin-bottom: 20px;
border-radius: 0 4px 4px 0;
}
.messageAttachmentContent>table,
.attachment__body {
font-family: Open Sans, sans-serif;
text-align: left;
font-size: 14px;
line-height: 20px;
color: #3F4350;
}
.messageAttachmentContent .attachment__author-icon {
width: 14px;
height: 14px;
margin-right: 5px;
border-radius: 50px;
vertical-align: middle;
}
.attachment__author-name {
opacity: 0.6;
}
.messageAttachmentContent p {
margin: 0;
}
.attachment__title {
padding: 0;
margin: 5px 0;
font-size: 14px;
font-weight: 600;
line-height: 18px;
}
.attachment__image {
max-height: 300px;
border: 1px solid transparent;
margin-bottom: 1em;
}
.attachment__thumb-image {
max-width: 100%;
max-height: 75px;
}
.attachment__thumb-container {
max-width: 80px;
width: max-content;
}
.attachment__wrapper {
width: 100%;
display: flex;
flex-direction: row;
gap: 12px;
}
.attachment__body {
flex: 1;
}
.messageAttachmentContent>table.attachment__footer-container {
color: #a3a3a3;
font-size: 12px;
}
.attachment__footer-icon {
width: 16px;
height: 16px;
}
.attachment__footer-container {
color: #a3a3a3;
font-size: 12px;
}
.messageAttachment_title {
padding-top: 1em;
font-weight: 600;
margin-bottom: 4px;
}
.pretext h1 {
font-size: 28px;
line-height: 32px;
}
.pretext h2 {
font-size: 25px;
line-height: 30px;
}
.pretext h3 {
font-size: 22px;
line-height: 25px;
}
.pretext h4 {
font-size: 19px;
line-height: 24px;
}
.pretext h5 {
font-size: 15px;
line-height: 20px;
}
.pretext h6 {
font-size: 1em;
line-height: 1.4em;
}
.pretext>* {
margin-bottom: 16px;
}
.messageAttachments {
margin-top: 22px;
}
.messageAttachments h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 500;
}
code {
padding: 2px 4px;
font-size: 90%;
background-color: rgba(63, 67, 80, 0.1);
border-radius: 4px;
}
.messageAttachments a {
background-color: unset !important;
border: none !important;
padding: unset !important;
}
</style>
<!-- this empty mj attribute tag is required by MJML to compile successfully -->
</head>
<body style="word-spacing:normal;">
@@ -507,7 +660,96 @@
</tbody>
</table>
</div>
<!--[if mso | IE]></td><td style="vertical-align:top;width:552px;" ><![endif]-->
<!--[if mso | IE]></td><![endif]-->
{{if .MessageAttachments}}
<div class="messageAttachments" style="margin-top: 22px;">
{{range .MessageAttachments}}
<div class="messageAttachment" style="vertical-align: top; font-family: Open Sans, sans-serif;" width="100%">
<div class="pretext" style="text-align: left; font-size: 14px; line-height: 20px; color: #3F4350; padding: 0px; font-family: Open Sans, sans-serif;">
{{.Pretext}}
</div>
<div class="messageAttachmentContent" style="border: 1px solid rgba(63, 67, 80, 0.16); margin-bottom: 20px; border-radius: 0 4px 4px 0; border-left: 4px solid {{.Color}}; padding: 12px; font-family: Open Sans, sans-serif;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="text-align: left; line-height: 20px; color: #3F4350; vertical-align: top; font-size: 14px; font-family: Open Sans, sans-serif;" width="100%" valign="top" align="left">
<tbody style="font-family: Open Sans, sans-serif;">
{{if or .AuthorIcon .AuthorName}}
<tr style="font-family: Open Sans, sans-serif;">
<td style="font-family: Open Sans, sans-serif;">
{{if .AuthorLink}}<a href="{{.AuthorLink}}" style="color: #1C58D9; font-family: Open Sans, sans-serif; text-decoration: none; background-color: unset; border: none; padding: unset;">{{end}}
{{if .AuthorIcon}}<img class="attachment__author-icon" alt="attachment author icon" src="{{.AuthorIcon}}" style="width: 14px; height: 14px; margin-right: 5px; border-radius: 50px; vertical-align: middle; font-family: Open Sans, sans-serif;" width="14" height="14">{{end}}
{{if .AuthorName}}<span class="attachment__author-name" style="opacity: 0.6; font-family: Open Sans, sans-serif;">{{.AuthorName}}</span>{{end}}
{{if .AuthorLink}}</a>{{end}}
</td>
</tr>
{{end}}
{{if .Title}}
<tr style="font-family: Open Sans, sans-serif;">
<td style="font-family: Open Sans, sans-serif;">
<h1 class="attachment__title" style="padding: 0; margin: 5px 0; font-size: 14px; line-height: 18px; font-weight: 500; font-family: Open Sans, sans-serif;">
{{if .TitleLink}}<a href="{{.TitleLink}}" style="color: #1C58D9; font-family: Open Sans, sans-serif; text-decoration: none; background-color: unset; border: none; padding: unset;">{{end}}
{{.Title}}
{{if .Title}}</a>{{end}}
</h1>
</td>
</tr>
{{end}}
</tbody>
</table>
<div class="attachment__wrapper" style="width: 100%; display: flex; flex-direction: row; gap: 12px; font-family: Open Sans, sans-serif;">
<div class="attachment__body" style="text-align: left; font-size: 14px; line-height: 20px; color: #3F4350; flex: 1; font-family: Open Sans, sans-serif;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align: top; font-size: 14px; color: #3F4350; font-family: Open Sans, sans-serif;" width="100%" valign="top">
<tbody style="font-family: Open Sans, sans-serif;">
<tr style="font-family: Open Sans, sans-serif;">
<td vertical-align="middle" class="messageButton" style="font-family: Open Sans, sans-serif;">
<div style="font-family: Open Sans, sans-serif;">{{.Text}}</div>
</td>
</tr>
{{if .ImageURL}}
<tr style="font-family: Open Sans, sans-serif;">
<td style="font-family: Open Sans, sans-serif;">
<img class="attachment__image" src="{{.ImageURL}}" style="max-height: 300px; border: 1px solid transparent; margin-bottom: 1em; font-family: Open Sans, sans-serif;">
</td>
</tr>
{{end}}
</tbody>
</table>
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align: top; font-size: 14px; table-layout: fixed; margin-bottom: 0.7em; font-family: Open Sans, sans-serif;" width="100%" valign="top">
{{range .FieldRows}}
<tr class="messageAttachment_row" style="font-family: Open Sans, sans-serif;">
{{ $length := len .Cells }}
{{range .Cells}}
<td class="messageAttachment_field" {{ if eq $length 1 }}colspan="2" {{end}} style="font-family: Open Sans, sans-serif;">
<div class="messageAttachment_title" style="padding-top: 1em; font-weight: 600; margin-bottom: 4px; font-family: Open Sans, sans-serif;">{{.Title}}</div>
<div style="font-family: Open Sans, sans-serif;">{{.Value}}</div>
</td>
{{end}}
</tr>
{{end}}
</table>
</div>
{{if .ThumbURL}}
<div class="attachment__thumb-container" style="max-width: 80px; width: max-content; font-family: Open Sans, sans-serif;">
<img class="attachment__thumb-image" src="{{.ThumbURL}}" style="max-width: 100%; max-height: 75px; font-family: Open Sans, sans-serif;">
</div>
{{end}}
</div>
{{if .Footer}}
<table class="attachment__footer-container" border="0" cellpadding="0" cellspacing="0" role="presentation" style="text-align: left; line-height: 20px; color: #a3a3a3; vertical-align: top; font-size: 14px; font-family: Open Sans, sans-serif;" width="100%" valign="top" align="left">
<tbody style="font-family: Open Sans, sans-serif;">
<tr style="font-family: Open Sans, sans-serif;">
<td style="font-family: Open Sans, sans-serif;">
{{if .FooterIcon}}<img class="attachment__footer-icon" src="{{.FooterIcon}}" style="width: 16px; height: 16px; vertical-align: middle; font-family: Open Sans, sans-serif;" width="16" height="16">{{end}}
<span style="font-size: 12px; font-family: Open Sans, sans-serif;">{{.Footer}}</span>
</td>
</tr>
</tbody>
</table>
{{end}}
</div>
</div>
{{end}}
</div>
{{end}}
<!--[if mso | IE]><td style="vertical-align:top;width:552px;" ><![endif]-->
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
<tbody>

Просмотреть файл

@@ -1,13 +1,21 @@
<mjml>
<mj-head>
<mj-include path="./partials/style.mjml" />
<mj-include path="partials/message_attachment_styles.mjml" />
</mj-head>
<mj-body css-class="emailBody">
<mj-wrapper mj-class="email">
<mj-include path="./partials/logo.mjml" />
<mj-include path="./partials/header.mjml" />
<mj-raw>{{range .Props.Posts}}<div class="postCard"></mj-raw>
<mj-include path="./partials/card.mjml" />
<mj-section css-class="messageCard" padding="0px">
<mj-group>
<mj-include path="./partials/message_avatar_col.mjml" />
<mj-include path="./partials/sender_info_col.mjml" />
<mj-include path="partials/message_attachment.html" type="html" />
<mj-include path="./partials/message_button.mjml" />
</mj-group>
</mj-section>
<mj-raw></div>{{end}}</mj-raw>
<mj-section padding="16px 0px 40px 0px">
<mj-column>

Просмотреть файл

@@ -1,42 +0,0 @@
<mj-section css-class="messageCard" padding="0px">
<mj-group>
<mj-column css-class="messageAvatarCol">
<mj-image css-class="messageAvatar" src="cid:{{.SenderPhoto}}" padding="0px" />
</mj-column>
<mj-column css-class="senderInfoCol" width=90% >
<mj-raw>
<tr>
<td>
<div class="postNameAndTime">
<div class="senderName">{{.SenderName}}</div>
{{if .Time}}
<div class="time">{{.Time}}</div>
{{end}}
{{if .ChannelName}}
<div class="channelBg">
{{if .ShowChannelIcon}}
<div class="channelLogo"><img src="{{$.Props.SiteURL}}/static/images/channel_icon.png" width=10px height=10px></img></div>
{{end}}
<div class="channelName">
{{if .OtherChannelMembersCount}}
<span class="gmChannelCount">{{.OtherChannelMembersCount}}</span>
{{end}}
{{.ChannelName}}
</div>
</div>
{{end}}
</div>
</td>
</tr>
</mj-raw>
<mj-text css-class="senderMessage" padding="0px">
{{.Message}}
</mj-text>
</mj-column>
<mj-column width=100%>
<mj-raw>{{if .MessageURL}}</mj-raw>
<mj-button href="{{.MessageURL}}" padding="16px 0px 0px 0px" css-class="messageButton">{{$.Props.MessageButton}}</mj-button>
<mj-raw>{{end}}</mj-raw>
</mj-column>
</mj-group>
</mj-section>

146
templates/partials/message_attachment.css Обычный файл
Просмотреть файл

@@ -0,0 +1,146 @@
.messageAttachments * {
font-family: Open Sans, sans-serif !important;
}
.messageAttachmentContent {
padding: 0px;
border: 1px solid rgba(63, 67, 80, 0.16);
margin-bottom: 20px;
border-radius: 0 4px 4px 0;
}
.messageAttachmentContent > table, .attachment__body {
font-family: Open Sans, sans-serif;
text-align: left;
font-size: 14px;
line-height: 20px;
color: #3F4350;
}
.messageAttachmentContent .attachment__author-icon {
width: 14px;
height: 14px;
margin-right: 5px;
border-radius: 50px;
vertical-align: middle;
}
.attachment__author-name {
opacity: 0.6;
}
.messageAttachmentContent p {
margin: 0;
}
.attachment__title {
padding: 0;
margin: 5px 0;
font-size: 14px;
font-weight: 600;
line-height: 18px;
}
.attachment__image {
max-height: 300px;
border: 1px solid transparent;
margin-bottom: 1em;
}
.attachment__thumb-image {
max-width: 100%;
max-height: 75px;
}
.attachment__thumb-container {
max-width: 80px;
width: max-content;
}
.attachment__wrapper {
width: 100%;
display: flex;
flex-direction: row;
gap: 12px;
}
.attachment__body {
flex: 1;
}
.messageAttachmentContent > table.attachment__footer-container {
color: #a3a3a3;
font-size: 12px;
}
.attachment__footer-icon {
width: 16px;
height: 16px;
}
.attachment__footer-container {
color: #a3a3a3;
font-size: 12px;
}
.messageAttachment_title {
padding-top: 1em;
font-weight: 600;
margin-bottom: 4px;
}
.pretext h1 {
font-size: 28px;
line-height: 32px;
}
.pretext h2 {
font-size: 25px;
line-height: 30px;
}
.pretext h3 {
font-size: 22px;
line-height: 25px;
}
.pretext h4 {
font-size: 19px;
line-height: 24px;
}
.pretext h5 {
font-size: 15px;
line-height: 20px;
}
.pretext h6 {
font-size: 1em;
line-height: 1.4em;
}
.pretext > * {
margin-bottom: 16px;
}
.messageAttachments {
margin-top: 22px;
}
.messageAttachments h1, h2, h3, h4, h5, h6 {
font-weight: 500;
}
code {
padding: 2px 4px;
font-size: 90%;
background-color: rgba(63, 67, 80, 0.1);
border-radius: 4px;
}
.messageAttachments a {
background-color: unset !important;
border: none !important;
padding: unset !important;
}

95
templates/partials/message_attachment.html Обычный файл
Просмотреть файл

@@ -0,0 +1,95 @@
{{if .MessageAttachments}}
<div class="messageAttachments">
{{range .MessageAttachments}}
<div class="messageAttachment" style="vertical-align:top;" width="100%">
<div class="pretext" style="font-family: Open Sans, sans-serif; text-align: left; font-size: 14px; line-height: 20px; color: #3F4350; padding: 0px;">
{{.Pretext}}
</div>
<div class="messageAttachmentContent" style="border-left: 4px solid {{.Color}}; padding: 12px;">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top; font-size: 14px" width="100%">
<tbody>
{{if or .AuthorIcon .AuthorName}}
<tr>
<td>
{{if .AuthorLink}}<a href="{{.AuthorLink}}">{{end}}
{{if .AuthorIcon}}<img class="attachment__author-icon" alt="attachment author icon" src="{{.AuthorIcon}}"/>{{end}}
{{if .AuthorName}}<span class="attachment__author-name">{{.AuthorName}}</span>{{end}}
{{if .AuthorLink}}</a>{{end}}
</td>
</tr>
{{end}}
{{if .Title}}
<tr>
<td>
<h1 class="attachment__title">
{{if .TitleLink}}<a href="{{.TitleLink}}">{{end}}
{{.Title}}
{{if .Title}}</a>{{end}}
</h1>
</td>
</tr>
{{end}}
</tbody>
</table>
<div class="attachment__wrapper">
<div class="attachment__body">
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top; font-size: 14px; color: #3F4350;" width="100%">
<tbody>
<tr>
<td vertical-align="middle" class="messageButton">
<div>{{.Text}}</div>
</td>
</tr>
{{if .ImageURL}}
<tr>
<td>
<img class="attachment__image" src="{{.ImageURL}}"/>
</td>
</tr>
{{end}}
</table>
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top; font-size: 14px; table-layout: fixed; margin-bottom: 0.7em;" width="100%">
{{range .FieldRows}}
<tr class="messageAttachment_row">
{{ $length := len .Cells }}
{{range .Cells}}
<td
class="messageAttachment_field"
{{ if eq $length 1 }}colspan="2"{{end}}
>
<div class="messageAttachment_title">{{.Title}}</div>
<div>{{.Value}}</div>
</td>
{{end}}
</tr>
{{end}}
</table>
</div>
{{if .ThumbURL}}
<div class="attachment__thumb-container">
<img class="attachment__thumb-image" src="{{.ThumbURL}}"/>
</div>
{{end}}
</div>
{{if .Footer}}
<table class="attachment__footer-container" border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top; font-size: 14px" width="100%">
<tbody>
<tr>
<td>
{{if .FooterIcon}}<img class="attachment__footer-icon" src="{{.FooterIcon}}" style="vertical-align: middle;"/>{{end}}
<span style="font-size: 12px;">{{.Footer}}</span>
</td>
</tr>
</tbody>
</table>
{{end}}
</div>
</div>
{{end}}
</div>
{{end}}

Просмотреть файл

@@ -0,0 +1,5 @@
<!-- this empty mj attribute tag is required by MJML to compile successfully -->
<mj-attributes/>
<mj-include type="css" path="message_attachment.css"/>
<mj-include type="css" css-inline="inline" path="message_attachment.css"/>

3
templates/partials/message_avatar_col.mjml Обычный файл
Просмотреть файл

@@ -0,0 +1,3 @@
<mj-column css-class="messageAvatarCol">
<mj-image css-class="messageAvatar" src="cid:{{.SenderPhoto}}" padding="0px" />
</mj-column>

5
templates/partials/message_button.mjml Обычный файл
Просмотреть файл

@@ -0,0 +1,5 @@
<mj-column width=100%>
<mj-raw>{{if .MessageURL}}</mj-raw>
<mj-button href="{{.MessageURL}}" padding="16px 0px 0px 0px" css-class="messageButton">{{$.Props.MessageButton}}</mj-button>
<mj-raw>{{end}}</mj-raw>
</mj-column>

30
templates/partials/sender_info_col.mjml Обычный файл
Просмотреть файл

@@ -0,0 +1,30 @@
<mj-column css-class="senderInfoCol" width=90% >
<mj-raw>
<tr>
<td>
<div class="postNameAndTime">
<div class="senderName">{{.SenderName}}</div>
{{if .Time}}
<div class="time">{{.Time}}</div>
{{end}}
{{if .ChannelName}}
<div class="channelBg">
{{if .ShowChannelIcon}}
<div class="channelLogo"><img src="{{$.Props.SiteURL}}/static/images/channel_icon.png" width=10px height=10px></img></div>
{{end}}
<div class="channelName">
{{if .OtherChannelMembersCount}}
<span class="gmChannelCount">{{.OtherChannelMembersCount}}</span>
{{end}}
{{.ChannelName}}
</div>
</div>
{{end}}
</div>
</td>
</tr>
</mj-raw>
<mj-text css-class="senderMessage" padding="0px">
{{.Message}}
</mj-text>
</mj-column>