plane/apiserver/templates/emails/notifications/issue-updates.html
Nikhil f27efb80e1
dev: email notifications (#3421)
* dev: create email notification preference model

* dev: intiate models

* dev: user notification preferences

* dev: create notification logs for the user.

* dev: email notification stacking and sending logic

* feat: email notification preference settings page.

* dev: delete subscribers

* dev: issue update ui implementation in email notification

* chore: integrate email notification endpoint.

* chore: remove toggle switch.

* chore: added labels part

* fix: refactored base design with tables

* dev: email notification templates

* dev: template updates

* dev: update models

* dev: update template for labels and new migrations

* fix: profile settings preference sidebar.

* dev: update preference endpoints

* dev: update the schedule to 5 minutes

* dev: update template with priority data

* dev: update templates

* chore: enable `issue subscribe` button for all users.

* chore: notification handling for external api

* dev: update origin request

---------

Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>
Co-authored-by: LAKHAN BAHETI <lakhanbaheti9@gmail.com>
Co-authored-by: Ramesh Kumar Chandra <rameshkumar2299@gmail.com>
Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
2024-01-23 17:49:22 +05:30

904 lines
39 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Updates on Issue</title>
<style type="text/css" emogrify="no">
html {
font-family: system-ui;
}
p,
h1,
h2,
h3,
h4,
ol,
ul {
margin: 0;
}
h-full {
height: 100%;
}
</style>
</head>
<body
bgcolor="#ffffff"
text="#3b3f44"
link="#3f76ff"
yahoo="fix"
style="background-color: #f7f9ff; margin: 20px"
>
<table
cellspacing="0"
cellpadding="0"
border="0"
style="
background-color: #f7f9ff;
width: 100%;
height: 100%;
padding-left: calc((100vw - 676px) / 2);
padding-right: calc((100vw - 676px) / 2);
"
>
<!-- Header -->
<tr>
<td>
<table style="width: 600px">
<tr>
<td>
<div style="margin: 20px">
<!-- TODO: Get Plane logo -->
<img
src="https://docs.plane.so/logos/logo.svg"
width="28"
height="28"
border="0"
/>
<span
style="font-weight: 700; font-size: 32px; color: #3f76ff"
>
Plane
</span>
</div>
</td>
</tr>
</table>
</td>
</tr>
<!-- Body -->
<tr>
<td>
<table style="width: 600px" celspacing="0">
<tr style="background-color: #fcfcfd">
<td style="color: #0b0c10; padding: 30px; border-radius: 4px">
<div>
<table>
<tr>
<td>
<p style="font-size: 1rem; font-weight: 600">
{{ issue.identifier }} updates
</p>
<p
style="
font-size: 1rem;
font-weight: 500;
line-height: 28px;
"
>
{{ issue.name }}
</p>
</td>
</tr>
</table>
<hr
style="
background-color: #f0f0f3;
height: 1px;
border: 0;
margin-top: 15px;
margin-bottom: 15px;
"
/>
<p style="font-size: 1rem; line-height: 28px">
{{ summary }}
<span
style="
font-size: 1rem;
font-weight: 700;
line-height: 28px;
"
>
{{ data.0.actor_detail.first_name}} {{data.0.actor_detail.last_name }}
</span>
</p>
<!-- Outer update/comment Box -->
<table
style="
background-color: #f7f9ff;
border-radius: 8px;
border-style: solid;
border-width: 1px;
border-color: #c1d0ff;
padding: 20px;
margin-top: 15px;
width: 100%;
white-space: nowrap;
max-width: 100%;
"
cellspacing="0"
>
<!-- Block Heading -->
<tr>
<td style="padding-bottom: 20px">
<p
style="
font-size: 0.8rem;
font-weight: 600;
color: #121a26;
"
>
Updates
</p>
</td>
</tr>
<!-- Property Updates -->
{% for update in data %}
<tr>
<td>
<table
cellspacing="0"
style="background-color: white; width: 100%"
>
<!-- action performer -->
<tr>
<td>
<table cellspacing="0">
<tr
style="
background-color: #ffffff;
border-radius: 8px;
margin-top: 20px;
"
>
<td style="padding-left: 15px">
<img
src="{{ update.actor_detail.avatar_url }}"
width="15"
height="15"
border="0"
/>
</td>
<td
style="
padding-top: 20px;
padding-bottom: 20px;
"
>
<p
style="
font-weight: 500;
font-size: 0.8rem;
color: #1c2024;
margin-left: 8px;
"
>
{{ update.actor_detail.first_name }} {{ update.actor_detail.last_name }}
</p>
</td>
<td style="width: fit-content">
<p
style="
font-weight: 500;
font-size: 0.6rem;
color: #80838d;
margin-left: 10px;
"
>
{{ update.activity_time }}
</p>
</td>
</tr>
</table>
</td>
</tr>
<!-- Only assignee changed -->
{% if update.changes.assignees %}
<tr>
<td
style="padding-left: 15px; padding-bottom: 20px"
>
<table>
<tr>
<td></td>
<td style="width: 55px">
<p
style="
font-size: 0.8rem;
font-weight: 500;
color: #525252;
"
>
Assignee:
</p>
</td>
{% for assignee in update.changes.assignees.old_value %}
<td>
<p
style="
font-size: 0.8rem;
font-weight: 500;
text-decoration: line-through;
color: #641723;
background-color: #feebec;
margin-left: 5px;
padding: 3px;
"
>
{{ assignee }}
</p>
</td>
{% endfor %}
{% if update.changes.assignees.old_value and update.changes.assignee.new_value %}
<td>
<i
data-lucide="move-right"
style="
color: #525252;
height: 15px;
width: 15px;
margin-left: 10px;
margin-right: 10px;
"
></i>
</td>
{% endif %}
{% for assignee in update.changes.assignees.new_value %}
<td>
<p
style="
font-size: 0.8rem;
font-weight: 500;
color: #0d74ce;
background-color: #e6f4fe;
padding: 3px;
"
>
{{ assginee }}
</p>
</td>
{% endfor %}
</tr>
</table>
</td>
</tr>
{% endif %}
<!-- due date changed -->
{% if update.changes.target_date %}
<tr>
<td
style="padding-left: 15px; padding-bottom: 20px"
>
<table>
<tr>
<td>
<i
data-lucide="calendar"
style="
color: #525252;
height: 12px;
width: 12px;
margin-right: 5px;
"
></i>
</td>
<td style="width: 55px">
<p
style="
font-size: 0.8rem;
font-weight: 500;
color: #525252;
"
>
Due Date:
</p>
</td>
<td>
<p
style="
font-size: 0.8rem;
font-weight: 500;
color: #171717;
margin-left: 5px;
"
>
{{ update.changes.target_date.new_value.0 }}
</p>
</td>
</tr>
</table>
</td>
</tr>
{% endif %} -->
<!-- duplicate changed -->
{% if update.changes.duplicate %}
<tr>
<td
style="padding-left: 15px; padding-bottom: 20px"
>
<table>
<tr>
<td>
<i
data-lucide="layout-panel-top"
style="
color: #525252;
height: 12px;
width: 12px;
margin-right: 5px;
"
></i>
</td>
<td style="width: 55px">
<p
style="
font-size: 0.8rem;
font-weight: 500;
color: #525252;
"
>
Duplicate:
</p>
</td>
{% for dup in update.changes.duplicate.new_value %}
<td>
<p
style="
font-size: 0.8rem;
font-weight: 500;
color: #3a5bc7;
margin-left: 5px;
"
>
{{ dup }}
</p>
</td>
{% endfor %}
</tr>
</table>
</td>
</tr>
{% endif %}
<!-- Labels -->
{% if update.changes.labels %}
<tr>
<td
style="padding-left: 15px; padding-bottom: 20px"
>
<table>
<tr>
<td valign="top">
<i
data-lucide="layout-panel-top"
style="
color: #525252;
height: 12px;
width: 12px;
margin-right: 5px;
"
></i>
</td>
<td valign="top">
<p
style="
font-size: 0.8rem;
font-weight: 500;
color: #525252;
margin-right: 5px;
"
>
Labels:
</p>
</td>
<td valign="top">
<table>
<tr>
{% for label in update.changes.labels.new_value %}
<td>
<p
style="
font-size: 0.8rem;
font-weight: 500;
color: #9747ff;
background-color: #9747ff1a;
padding: 3px;
padding-left: 5px;
padding-right: 5px;
margin-right: 4px;
border-radius: 2px;
"
>
{{ label }}
</p>
</td>
{% endfor %}
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
{% endif %}
<!-- State changed -->
{% if update.changes.state %}
<tr>
<td>
<tr>
<td
style="
padding-left: 15px;
padding-bottom: 20px;
"
>
<table>
<tr>
<td>
<i
data-lucide="calendar"
style="
color: #525252;
height: 12px;
width: 12px;
margin-right: 5px;
"
></i>
</td>
<td>
<p
style="
font-size: 0.8rem;
font-weight: 500;
color: #525252;
"
>
State:
</p>
</td>
<td>
<p
style="
font-size: 0.8rem;
font-weight: 600;
color: #60646c;
"
>
{{ update.changes.state.old_value.0 }}
</p>
</td>
<td>-></td>
<td>
<p
style="
font-size: 0.8rem;
font-weight: 600;
color: #60646c;
"
>
{{ update.changes.state.new_value.0 }}
</p>
</td>
</tr>
</table>
</td>
</tr>
</td>
</tr>
{% endif %}
<!-- Link Added -->
{% if update.changes.link %}
<tr>
<td
style="padding-left: 15px; padding-bottom: 20px"
>
<table>
<tr>
<td>
<i
data-lucide="layout-panel-top"
style="
color: #525252;
height: 12px;
width: 12px;
margin-right: 5px;
"
></i>
</td>
<td>
<p
style="
font-size: 0.8rem;
font-weight: 500;
color: #525252;
margin-right: 5px;
"
>
Link:
</p>
</td>
<td>
<a
href=""
style="
font-size: 0.8rem;
font-weight: 600;
color: #3a5bc7;
"
>
{{ update.changes.link.new_value.0 }}
</a>
</td>
</tr>
</table>
</td>
</tr>
{% endif %}
<!-- Priority changed -->
{% if update.changes.priority %}
<tr>
<td style="padding-left: 15px; padding-bottom: 20px">
<table>
<tr>
<td>
<i
data-lucide="layout-panel-top"
style="
color: #525252;
height: 12px;
width: 12px;
margin-right: 5px;
"
></i>
</td>
<td>
<p
style="
font-size: 0.8rem;
font-weight: 500;
color: #525252;
margin-right: 5px;
"
>
Priority:
</p>
</td>
<td>
<p
style="
font-size: 0.8rem;
padding: 2px;
font-weight: 500;
{% if update.changes.priority.old_value.0 == 'urgent' %}background-color: #EF4444; color: white;{% endif %}
{% if update.changes.priority.old_value.0 == 'high' %}background-color: #F97316; color: white;{% endif %}
{% if update.changes.priority.old_value.0 == 'medium' %}background-color: #EAB308; color: white;{% endif %}
{% if update.changes.priority.old_value.0 == 'low' %}background-color: #3F76FF; color: white;{% endif %}
{% if update.changes.priority.old_value.0 == 'none' %}background-color: #A3A3A3; color: white;{% endif %}
"
>
{{ update.changes.priority.old_value.0 }}
</p>
</td>
<td
style="
padding-left: 10px;
padding-right: 10px;
"
>
->
</td>
<td>
<p
style="
font-size: 0.8rem;
padding: 2px;
font-weight: 500;
{% if update.changes.priority.old_value.0 == 'urgent' %}background-color: #EF4444; color: white;{% endif %}
{% if update.changes.priority.old_value.0 == 'high' %}background-color: #F97316; color: white;{% endif %}
{% if update.changes.priority.old_value.0 == 'medium' %}background-color: #EAB308; color: white;{% endif %}
{% if update.changes.priority.old_value.0 == 'low' %}background-color: #3F76FF; color: white;{% endif %}
{% if update.changes.priority.old_value.0 == 'none' %}background-color: #A3A3A3; color: white;{% endif %}
"
>
{{ update.changes.priority.new_value.0 }}
</p>
</td>
</tr>
</table>
</td>
</tr>
{% endif %}
<!-- Blocking changed -->
{% if update.changes.blocking %}
<tr>
<td
style="padding-left: 15px; padding-bottom: 20px"
>
<table>
<tr>
<td>
<i
data-lucide="layout-panel-top"
style="
color: #525252;
height: 12px;
width: 12px;
margin-right: 5px;
"
></i>
</td>
<td>
<p
style="
font-size: 0.8rem;
font-weight: 500;
color: #525252;
margin-right: 5px;
"
>
Blocking:
</p>
</td>
{% for bl in update.changes.blocking.new_value %}
<td>
<a
href=""
style="font-size: 0.8rem; color: #3358d4"
>
{{ bl }}
</a>
</td>
{% endfor %}
</tr>
</table>
</td>
</tr>
{% endif %}
</table>
</td>
</tr>
{% endfor %}
</table>
<!-- Comments outer update Box -->
{% if comments %}
<table
style="
background-color: #f7f9ff;
border-radius: 8px;
border-style: solid;
border-width: 1px;
border-color: #c1d0ff;
padding: 20px;
margin-top: 15px;
width: 600px;
max-width: 600px;
"
cellspacing="0"
>
<!-- Block Heading -->
<tr>
<td>
<p
style="
font-size: 0.8rem;
font-weight: 600;
color: #121a26;
"
>
Comments
</p>
</td>
</tr>
<!-- Comments Updates -->
<tr>
<td>
<table
cellspacing="0"
style="background-color: white; width: 100%"
></table>
</td>
</tr>
<!-- Comments -->
<tr>
<td>
<table cellspacing="0" style="padding-top: 20px">
<tr style="border-radius: 8px">
<td valign="top">
<div
style="
height: 25px;
width: 25px;
border-radius: 20px;
background-color: #4f3422;
text-align: center;
justify-items: center;
"
>
<span
style="
color: white;
font-weight: 500;
text-align: center;
padding-top: 0px;
font-size: 12px;
"
>S</span
>
</div>
<!-- <img src="https://docs.plane.so/logos/logo.svg" width="25"
height="25" border="0" /> -->
</td>
{% for comment in comments %}
<td style="padding-bottom: 20px">
<table>
<tr>
<td>
<p
style="
font-weight: 500;
font-size: 0.8rem;
color: #1c2024;
margin-left: 8px;
"
>
{{ comment.actor_detail.first_name }} {{ comment.actor_detail.last_name }}
</p>
</td>
</tr>
{% for actor_comment in comment.actor_comments %}
<tr>
<td>
<div
style="
padding-left: 10px;
padding-right: 10px;
line-height: 24px;
padding-top: 15px;
margin-left: 10px;
padding-bottom: 15px;
background-color: white;
font-size: 0.8rem;
color: #525252;
margin-top: 5px;
border-radius: 4px;
"
>
{{ actor_comment.new_value.0 }}
</div>
</td>
</tr>
{% endfor %}
</table>
</td>
{% endfor %}
</tr>
</table>
</td>
</tr>
</table>
{% endif %}
</div>
<button
onclick="window.location.href='{{ issue.issue_url }}'"
href="{{ issue.issue_url }}"
style="
background-color: #3e63dd;
padding: 10px 15px;
border: 1px solid #2f4ba8;
border-radius: 4px;
margin-top: 15px;
cursor: pointer;
font-size: 0.8rem;
color: white;
"
>
View issue
</button>
</td>
</tr>
</table>
</td>
</tr>
<!-- Footer -->
<tr>
<td>
<table style="width: 100%; padding: 20px; justify-content: center">
<tr>
<td>
<div style="font-size: 0.8rem; color: #1c2024">
This email was sent to
<a
href="mailto:"
style="
color: #3a5bc7;
font-weight: 500;
text-decoration: none;
"
>{{ receiver.email }}.</a
>
If you'd rather not receive this kind of email,
<a
href="{{ issue_unsubscribe }}"
style="color: #3a5bc7; text-decoration: none"
>you can unsubscribe to the issue</a
>
or
<a
href="{{ user_preference }}"
style="color: #3a5bc7; text-decoration: none"
>manage your email preferences</a
>.
<!-- Github | LinkedIn | Twitter -->
<div style="margin-top: 60px; float: right">
<a
href="https://github.com/makeplane"
target="_blank"
style="margin-left: 10px; text-decoration: none"
>
<img
src="https://creative-assets.mailinblue.com/editor/social-icons/rounded_colored/github_32px.png"
width="25"
height="25"
border="0"
style="display: inline-block"
/>
</a>
<a
href="https://www.linkedin.com/company/planepowers/"
target="_blank"
style="margin-left: 10px; text-decoration: none"
>
<img
src="https://creative-assets.mailinblue.com/editor/social-icons/rounded_colored/linkedin_32px.png"
width="25"
height="25"
border="0"
style="display: inline-block"
/>
</a>
<a
href="https://twitter.com/planepowers"
target="_blank"
style="margin-left: 10px; text-decoration: none"
>
<img
src="https://creative-assets.mailinblue.com/editor/social-icons/rounded_colored/twitter_32px.png"
width="25"
height="25"
border="0"
style="display: inline-block"
/>
</a>
</div>
</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
<!-- Lucid Icon Scripts -->
<script src="https://unpkg.com/lucide@latest"></script>
<script>
lucide.createIcons();
</script>
</body>
</html>