Merge branch 'rebrand-ui' of https://github.com/frappe/frappe into rebrand-ui

This commit is contained in:
prssanna 2021-01-21 11:27:51 +05:30
commit dff870ead6
12 changed files with 128 additions and 73 deletions

View file

@ -466,7 +466,7 @@ def sendmail(recipients=[], sender="", subject="No Subject", message="No Message
attachments=None, content=None, doctype=None, name=None, reply_to=None,
cc=[], bcc=[], message_id=None, in_reply_to=None, send_after=None, expose_recipients=None,
send_priority=1, communication=None, retry=1, now=None, read_receipt=None, is_notification=False,
inline_images=None, template=None, args=None, header=None, print_letterhead=False):
inline_images=None, template=None, args=None, header=None, print_letterhead=False, with_container=False):
"""Send email using user's default **Email Account** or global default **Email Account**.
@ -492,6 +492,7 @@ def sendmail(recipients=[], sender="", subject="No Subject", message="No Message
:param template: Name of html template from templates/emails folder
:param args: Arguments for rendering the template
:param header: Append header in email
:param with_container: Wraps email inside a styled container
"""
text_content = None
if template:
@ -514,7 +515,7 @@ def sendmail(recipients=[], sender="", subject="No Subject", message="No Message
attachments=attachments, reply_to=reply_to, cc=cc, bcc=bcc, message_id=message_id, in_reply_to=in_reply_to,
send_after=send_after, expose_recipients=expose_recipients, send_priority=send_priority,
communication=communication, now=now, read_receipt=read_receipt, is_notification=is_notification,
inline_images=inline_images, header=header, print_letterhead=print_letterhead)
inline_images=inline_images, header=header, print_letterhead=print_letterhead, with_container=False)
whitelisted = []
guest_methods = []

View file

@ -250,12 +250,13 @@ class EMail:
return self.msg_root.as_string(policy=policy.SMTPUTF8)
def get_formatted_html(subject, message, footer=None, print_html=None,
email_account=None, header=None, unsubscribe_link=None, sender=None):
email_account=None, header=None, unsubscribe_link=None, sender=None, with_container=False):
if not email_account:
email_account = get_outgoing_email_account(False, sender=sender)
rendered_email = frappe.get_template("templates/emails/standard.html").render({
"brand_logo": get_app_logo(),
"brand_logo": get_brand_logo(),
"with_container": with_container,
"site_url": get_url(),
"header": get_header(header),
"content": message,
@ -275,14 +276,14 @@ def get_formatted_html(subject, message, footer=None, print_html=None,
return html
@frappe.whitelist()
def get_email_html(template, args, subject, header=None):
def get_email_html(template, args, subject, header=None, with_container=False):
import json
with_container = cint(with_container)
args = json.loads(args)
if header and header.startswith('['):
header = json.loads(header)
email = frappe.utils.jinja.get_email_from_template(template, args)
return get_formatted_html(subject, email[0], header=header)
return get_formatted_html(subject, email[0], header=header, with_container=with_container)
def inline_style_in_html(html):
''' Convert email.css and html to inline-styled html
@ -369,10 +370,10 @@ def get_footer(email_account, footer=None):
if email_account and email_account.footer:
args.update({'email_account_footer': email_account.footer})
company_address = frappe.db.get_default("email_footer_address")
sender_address = frappe.db.get_default("email_footer_address")
if company_address:
args.update({'company_address': company_address})
if sender_address:
args.update({'sender_address': sender_address})
if not cint(frappe.db.get_default("disable_standard_email_footer")):
args.update({'default_mail_footer': frappe.get_hooks('default_mail_footer')})
@ -470,3 +471,6 @@ def get_header(header=None):
def sanitize_email_header(str):
return str.replace('\r', '').replace('\n', '')
def get_brand_logo():
return get_app_logo()

View file

@ -24,7 +24,7 @@ def send(recipients=None, sender=None, subject=None, message=None, text_content=
attachments=None, reply_to=None, cc=None, bcc=None, message_id=None, in_reply_to=None, send_after=None,
expose_recipients=None, send_priority=1, communication=None, now=False, read_receipt=None,
queue_separately=False, is_notification=False, add_unsubscribe_link=1, inline_images=None,
header=None, print_letterhead=False):
header=None, print_letterhead=False, with_container=False):
"""Add email to sending queue (Email Queue)
:param recipients: List of recipients.
@ -48,6 +48,7 @@ def send(recipients=None, sender=None, subject=None, message=None, text_content=
:param add_unsubscribe_link: Send unsubscribe link in the footer of the Email, default 1.
:param inline_images: List of inline images as {"filename", "filecontent"}. All src properties will be replaced with random Content-Id
:param header: Append header in email (boolean)
:param with_container: Wraps email inside styled container
"""
if not unsubscribe_method:
unsubscribe_method = "/api/method/frappe.email.queue.unsubscribe"
@ -130,7 +131,7 @@ def send(recipients=None, sender=None, subject=None, message=None, text_content=
email_content = get_formatted_html(subject, message,
email_account=email_account, header=header,
unsubscribe_link=unsubscribe_link)
unsubscribe_link=unsubscribe_link, with_container=with_container)
# add to queue
add(recipients, sender, subject,

View file

@ -1,4 +1,4 @@
frappe.preview_email = function(template, args, header, only_html=false) {
frappe.preview_email = function(template, args, header, with_container=false, only_html=false) {
return frappe
.call({
method: 'frappe.email.email_body.get_email_html',
@ -6,7 +6,8 @@ frappe.preview_email = function(template, args, header, only_html=false) {
subject: 'Test',
template,
args,
header
header,
with_container
}
})
.then(r => {

View file

@ -52,7 +52,6 @@ hr {
.body-table {
font-family: $font-stack;
background-color: $gray-100;
border-collapse: collapse;
table-layout: fixed;
margin: 0 auto;
@ -60,7 +59,6 @@ hr {
height: 100% !important;
width: 100% !important;
font-weight: normal;
color: $text-color;
font-family: $font-stack;
font-size: 14px;
line-height: 1.4;
@ -70,35 +68,7 @@ hr {
}
.body-content {
padding: 60px 40px;
}
}
.email-container {
max-width: 600px;
border-spacing: 0;
padding: 30px;
border-radius: $border-radius-lg;
overflow: hidden;
background-color: white;
.email-body > tr {
border-collapse: collapse;
border-bottom: none;
}
.brand-logo {
margin: auto;
text-align: center;
border: 0;
outline: none;
text-decoration: none;
max-height: 40px;
width: auto;
}
}
@media only screen and (max-width: 600px) {
.email-container {
width: 90%;
padding: 20px 0;
}
}
@ -118,12 +88,11 @@ hr {
}
.email-footer {
font-size: 13px;
font-size: 12px;
line-height: 20px;
}
.email-header {
.brand-image {
width: 24px;
height: 24px;
@ -137,10 +106,36 @@ hr {
font-weight: 600;
}
.body-table.has-header {
.email-body {
border-radius: 0 0 4px 4px;
border-top: none;
.body-table.with-container {
background-color: $gray-100;
color: $text-color;
.body-content {
padding: 60px 40px;
}
.email-container {
max-width: 600px;
border-spacing: 0;
padding: 30px;
border-radius: $border-radius-lg;
overflow: hidden;
background-color: white;
.email-body {
border-radius: 0 0 4px 4px;
border-top: none;
tr {
border-collapse: collapse;
border-bottom: none;
}
}
.brand-logo {
margin: auto;
text-align: center;
border: 0;
outline: none;
text-decoration: none;
max-height: 40px;
width: auto;
}
}
.email-footer {
@ -148,8 +143,14 @@ hr {
}
}
@media only screen and (max-width: 600px) {
.body-table.with-container .email-container {
width: 90%;
}
}
.email-footer-container {
margin-top: 40px;
margin-top: 60px;
& > div:not(:last-child) {
margin-bottom: 5px;

View file

@ -322,15 +322,16 @@ def send_summary(timespan):
all_users = [user.email for user in get_enabled_system_users()]
frappe.sendmail(
subject='{} energy points summary'.format(timespan),
recipients=all_users,
template="energy_points_summary",
args={
subject = '{} energy points summary'.format(timespan),
recipients = all_users,
template = "energy_points_summary",
args = {
'top_performer': user_points[0],
'top_reviewer': max(user_points, key=lambda x:x['given_points']),
'standings': user_points[:10], # top 10
'footer_message': get_footer_message(timespan).format(from_date, to_date)
}
'footer_message': get_footer_message(timespan).format(from_date, to_date),
},
with_container = 1
)
def get_footer_message(timespan):

View file

@ -6,10 +6,10 @@
</div>
{% endif %}
<!-- company_address -->
{% if company_address %}
<div class="company-address">
{% for line in company_address.splitlines(True) %}
<!-- sender_address -->
{% if sender_address %}
<div class="sender-address">
{% for line in sender_address.splitlines(True) %}
<div>{{ line }}</div>
{% endfor %}
</div>

View file

@ -1,19 +1,30 @@
{% from "frappe/templates/includes/avatar_macro.html" import avatar %}
{% if top_performer.energy_points %}
<h1 class="text-2xl">{{ _('Top Performer') }}</h1>
<h1 class="text-2xl">{{ _('Top Performer') }} 🏆 </h1>
<p>
<span class="text-2xl"> 🏆 </span> {{ frappe.get_fullname(top_performer.user) }}
<span class="text-muted">
{{ _('gained {0} points').format(frappe.utils.cint(top_performer.energy_points)) }}
{{ avatar(top_performer.user) }} &nbsp;
{{
_('{0} gained {1} points').format(
frappe.get_fullname(top_performer.user),
frappe.utils.cint(top_performer.energy_points)
)
}}
</span>
</p>
{% endif %}
{% if top_reviewer.given_points %}
<h1 class="text-xl">{{ _('Top Reviewer') }}</h1>
<h1 class="text-xl">{{ _('Top Reviewer') }} ❤️ </h1>
<p>
<span class="text-2xl"> ❤️ </span> {{ frappe.get_fullname(top_reviewer.user) }}
<span class="text-muted">
{{ _('gave {0} points').format(frappe.utils.cint(top_reviewer.given_points)) }}
{{ avatar(top_reviewer.user) }} &nbsp;
{{
_('{0} gave {1} points').format(
frappe.get_fullname(top_reviewer.user),
frappe.utils.cint(top_reviewer.given_points)
)
}}
</span>
</p>
{% endif %}

View file

@ -8,11 +8,12 @@
</head>
<body>
<table class="body-table {% if header %}has-header{% endif %}" cellpadding="0" cellspacing="0">
<table class="body-table {% if header or with_container %} with-container {% endif %}" cellpadding="0" cellspacing="0">
<tr>
<td class="body-content" align="center" valign="top">
<table class="email-container" border="0" cellpadding="0" cellspacing="0"
width="{% if header %}600{% else %}100%{% endif %}">
width="{% if header %} 600 {% else %} 100% {% endif %}">
{% if header and brand_logo %}
<tr>
<td width="40" align="left" valign="middle">
<a href="{{ site_url or 'https://frappeframework.com' }}">
@ -24,6 +25,7 @@
</a>
</td>
</tr>
{% endif %}
<tr>
<td valign="top">
{{ header or "" }}
@ -33,12 +35,10 @@
<td valign="top">
<table class="email-body" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<!-- <td width="15"></td> -->
<td valign="top">
<p>{{ content }}</p>
<p>{{ signature }}</p>
</td>
<!-- <td width="15"></td> -->
</tr>
</table>
</td>

View file

@ -0,0 +1,20 @@
{% macro avatar(user_id=None, css_style=None) %}
{% set user_info = frappe.utils.get_user_info_for_avatar(user_id) %}
<span class="avatar avatar-small" title="{{ user_info.name }}">
{% if user_info.image %}
<img
class="avatar-frame standard-image"
src="{{ user_info.image }}"
style="{{ css_style }}"
title="{{ user_info.name }}">
</span>
{% else %}
<span
class="avatar-frame standard-image"
style="{{ css_style }}"
title="{{ user_info.name }}">
{{ user_info.name[:1] }}
</span>
{% endif %}
</span>
{% endmacro %}

View file

@ -1413,4 +1413,18 @@ def validate_json_string(string):
try:
json.loads(string)
except (TypeError, ValueError):
raise frappe.ValidationError
raise frappe.ValidationError
def get_user_info_for_avatar(user_id):
user_info = {
"email": user_id,
"image": "",
"name": user_id
}
try:
user_info["email"] = frappe.get_cached_value("User", user_id, "email")
user_info["name"] = frappe.get_cached_value("User", user_id, "fullname")
user_info["image"] = frappe.get_cached_value("User", user_id, "user_image")
except Exception:
frappe.local.message_log = []
return user_info

View file

@ -292,5 +292,6 @@ VALID_UTILS = (
"is_subset",
"generate_hash",
"formatdate",
"get_user_info_for_avatar",
"get_abbr"
)