Merge branch 'rebrand-ui' of https://github.com/frappe/frappe into rebrand-ui
This commit is contained in:
commit
dff870ead6
12 changed files with 128 additions and 73 deletions
|
|
@ -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 = []
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 => {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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) }}
|
||||
{{
|
||||
_('{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) }}
|
||||
{{
|
||||
_('{0} gave {1} points').format(
|
||||
frappe.get_fullname(top_reviewer.user),
|
||||
frappe.utils.cint(top_reviewer.given_points)
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
20
frappe/templates/includes/avatar_macro.html
Normal file
20
frappe/templates/includes/avatar_macro.html
Normal 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 %}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -292,5 +292,6 @@ VALID_UTILS = (
|
|||
"is_subset",
|
||||
"generate_hash",
|
||||
"formatdate",
|
||||
"get_user_info_for_avatar",
|
||||
"get_abbr"
|
||||
)
|
||||
Loading…
Add table
Reference in a new issue