Skip to content
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
c3fb2bb
update base-html
odeimaiz Mar 26, 2025
32c56b0
parametrize base.html
odeimaiz Mar 26, 2025
316b330
pass product metadata
odeimaiz Mar 26, 2025
7e29b7e
minor
odeimaiz Mar 26, 2025
7bf0043
extend ProductData model
odeimaiz Mar 26, 2025
4a63e42
HttpUrl
odeimaiz Mar 26, 2025
dc02a80
renaming
odeimaiz Mar 26, 2025
9d6551e
add logo and strong_color to Vendor's model
odeimaiz Mar 26, 2025
e9a38d9
ProductData
odeimaiz Mar 26, 2025
9d6f69d
minor
odeimaiz Mar 26, 2025
f34fe9e
set product info
odeimaiz Mar 26, 2025
e7e4b6c
minor
odeimaiz Mar 26, 2025
500797c
Merge branch 'master' into enh/prettify-base-email
odeimaiz Mar 27, 2025
f254081
no need to pass the args
odeimaiz Mar 27, 2025
e715f71
Merge branch 'enh/prettify-base-email' of github.com:odeimaiz/osparc-…
odeimaiz Mar 27, 2025
a90238c
strong-button for links
odeimaiz Mar 27, 2025
8851478
Manrope by default
odeimaiz Mar 27, 2025
66d25cc
prettify button
odeimaiz Mar 27, 2025
f50cae5
more buttons
odeimaiz Mar 27, 2025
a98d9b9
inline styling
odeimaiz Mar 27, 2025
7b4f3c1
minor
odeimaiz Mar 27, 2025
1771fa1
buttons templated strong color
odeimaiz Mar 27, 2025
9c2c0f3
minor
odeimaiz Mar 27, 2025
c64124e
Merge branch 'master' into enh/prettify-base-email
odeimaiz Mar 28, 2025
423a842
product ui data
odeimaiz Mar 28, 2025
6e2eb50
.ui.
odeimaiz Mar 28, 2025
f5f31c4
minor
odeimaiz Mar 28, 2025
0977198
ui -> product_ui
odeimaiz Mar 28, 2025
04e75de
1st try
odeimaiz Mar 28, 2025
9073d4f
back
odeimaiz Mar 28, 2025
c9c72bf
typo
odeimaiz Mar 28, 2025
081bbe1
fix test
odeimaiz Mar 28, 2025
130a9b7
product_ui -> ui
odeimaiz Mar 28, 2025
df04634
add defaults
odeimaiz Mar 28, 2025
1c63495
vendor.ui
odeimaiz Mar 28, 2025
2a0c1d6
Merge branch 'master' into enh/prettify-base-email
odeimaiz Mar 31, 2025
47087d5
Merge branch 'master' into enh/prettify-base-email
odeimaiz Mar 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,17 @@ class UserData:
email: str


@dataclass(frozen=True)
class ProductUIData:
logo_url: str
strong_color: str


@dataclass(frozen=True)
class ProductData:
product_name: ProductName
display_name: str
vendor_display_inline: str
support_email: str
homepage_url: str
ui: ProductUIData
Original file line number Diff line number Diff line change
@@ -1,32 +1,110 @@
{% set default_strong_color = "rgb(131, 0, 191)" %}
{% set default_logo = "https://raw.githubusercontent.com/ITISFoundation/osparc-simcore/refs/heads/master/services/static-webserver/client/source/resource/osparc/osparc-black.svg" %}
{% set default_homepage = "https://osparc.io/" %}

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{% endblock %}</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
color: #333;
}
.container {
background-color: #f9f9f9;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
a {
color: #007bff;
text-decoration: none;
}
body {
font-family: Manrope, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f4f4;
}
.email-container {
max-width: 600px;
margin: 20px auto;
background-color: #ffffff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.header {
display: flex;
align-items: center;
border-bottom: 2px solid #ddd;
padding-bottom: 10px;
margin-bottom: 20px;
}
.logo {
height: 40px;
}
.content {
color: #333;
font-size: 16px;
line-height: 1.5;
}
a {
color: #007bff;
text-decoration: none;
}
.strong-button {
cursor: pointer;
background-color: {{ product.ui.strong_color | default(default_strong_color) }};
color: white;
padding: 10px;
border: none;
border-radius: 4px;
overflow: hidden;
white-space: nowrap;
user-select: none;
touch-action: none;
outline: none;
}
.strong-button a {
font-size: 16px;
color: white;
text-decoration: none;
display: block;
width: 100%;
height: 100%;
text-align: center;
}
.footer {
margin-top: 20px;
padding-top: 15px;
border-top: 2px solid #ddd;
font-size: 14px;
text-align: center;
color: #666;
}
.footer a {
color: #007bff;
text-decoration: none;
}
.github-logo {
height: 20px;
vertical-align: bottom;
}
</style>
</head>
<body>
<div class="container">
{% block content %}
{% endblock %}
<div class="email-container">
<div class="header">
<a href="{{ product.homepage_url | default(default_homepage) }}" target="_blank" rel="noopener noreferrer">
<img src="{{ product.ui.logo_url | default(default_logo) }}" alt="Logo" class="logo">
</a>
</div>

<div class="content">
{% block content %}
{% endblock %}
</div>

<div class="footer">
<p>
Visit the <a href="{{ product.homepage_url | default(default_homepage) }}" target="_blank" rel="noopener noreferrer">Platform</a> |
Need help? <a href="mailto:{{ product.support_email }}">Support</a> |
Powered by oSPARC
<a href="https://github.com/ITISFoundation/osparc-simcore" target="_blank" rel="noopener noreferrer">
<img src="https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png" alt="GitHub" class="github-logo">
</a>
</p>
</div>
</div>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
</p>

<p>
<a href="{{ link }}">{{ link }}</a>
<!-- Many email clients strip or ignore certain CSS properties, including them inline -->
<button class="strong-button" style="border-radius: 4px;">
<a href="{{ link }}" style="color: white;">Change email</a>
</button>
</p>

<p>Please don't hesitate to contact us at {{ product.support_email }} if you need further help.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
{% block content %}
<p>Dear {{ user.first_name }},</p>
<p>Thank you for your interest in {{ product.display_name }}. We are pleased to provide you with a one-time invitation link to register on the platform.</p>
<p>Click <a href="{{ link }}">here</a> to access the registration page.</p>
<p>
<!-- Many email clients strip or ignore certain CSS properties, including them inline -->
<button class="strong-button" style="border-radius: 4px;">
<a href="{{ link }}" style="color: white;">Register</a>
</button>
</p>
<p>Please follow the on-screen information and proceed with your registration.</p>
<p>If any problem should occur, please feel free to contact us at {{ product.support_email }}.</p>
<p>Enjoy {{ product.display_name }}!</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
<p>Dear {{ user.first_name }},</p>
<p>Thank you for your interest in {{ product.display_name }}. You have successfully registered for {{ host }}.</p>
<p>Please activate your account via the link below:</p>
<p><a href="{{ link }}">{{ link }}</a></p>
<p>
<button class="strong-button" style="border-radius: 4px;">
<a href="{{ link }}" style="color: white;">Activate</a>
</button>
</p>
<p>Please don't hesitate to contact us at {{ product.support_email }} if you need further help.</p>
<p>Best Regards,</p>
<p>The <i>{{ product.display_name }}</i> Team</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
{% if success %}

<p>To complete the process, please click the link below:</p>
<p><a href="{{ link }}">{{ link }}</a></p>
<p>
<button class="strong-button" style="border-radius: 4px;">
<a href="{{ link }}" style="color: white;">Reset Password</a>
</button>
</p>

{% else %}

Expand All @@ -16,7 +20,7 @@

{% endif %}

<p>If you did not request this, please contact us immediatly at {{ product.support_email }} for security reasons.</p>
<p>If you did not request this, please contact us immediately at {{ product.support_email }} for security reasons.</p>

<p>Best Regards,</p>
<p>The <i>{{ product.display_name }}</i> Team</p>
Expand Down
14 changes: 12 additions & 2 deletions packages/notifications-library/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import notifications_library
import pytest
from models_library.products import ProductName
from notifications_library._models import ProductData, UserData
from notifications_library._models import ProductData, ProductUIData, UserData
from notifications_library.payments import PaymentData
from pydantic import EmailStr
from pytest_simcore.helpers.typing_env import EnvVarsDict
Expand Down Expand Up @@ -44,7 +44,7 @@ def external_envfile_dict(external_envfile_dict: EnvVarsDict) -> EnvVarsDict:


#
# mock data for templaes
# mock data for templates
#


Expand All @@ -55,11 +55,21 @@ def product_data(
) -> ProductData:
vendor: Vendor = product["vendor"]

product_ui = ProductUIData(
logo_url=vendor.get("ui", {}).get(
"logo_url",
"https://raw.githubusercontent.com/ITISFoundation/osparc-simcore/refs/heads/master/services/static-webserver/client/source/resource/osparc/osparc-white.svg",
),
strong_color=vendor.get("ui", {}).get("strong_color", "rgb(131, 0, 191)"),
)

return ProductData( # type: ignore
product_name=product_name,
display_name=product["display_name"],
vendor_display_inline=f"{vendor.get('name','')}, {vendor.get('address','')}",
support_email=product["support_email"],
homepage_url=vendor.get("url", "https://osparc.io/"),
ui=product_ui,
)


Expand Down
8 changes: 6 additions & 2 deletions packages/notifications-library/tests/test__render.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
from pathlib import Path

from models_library.products import ProductName
from notifications_library._models import ProductData
from notifications_library._render import (
create_render_env_from_folder,
create_render_env_from_package,
)
from notifications_library._templates import _print_tree, _templates_dir


def test_render_env_from_folder(tmp_path: Path, product_name: ProductName):
def test_render_env_from_folder(
tmp_path: Path, product_name: ProductName, product_data: ProductData
):

pkg_env = create_render_env_from_package()

Expand All @@ -27,4 +30,5 @@ def test_render_env_from_folder(tmp_path: Path, product_name: ProductName):
product_template = consolidated_env.get_template(f"{product_name}/base.html")
common_template = pkg_env.get_template("base.html")

assert product_template.render() == common_template.render()
data = {"product": product_data}
assert product_template.render(data) == common_template.render(data)
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
""" Products table
"""Products table

- List of products served by the simcore platform
- Products have a name and an associated host (defined by a regex)
- Every product has a front-end with exactly the same name
- List of products served by the simcore platform
- Products have a name and an associated host (defined by a regex)
- Every product has a front-end with exactly the same name
"""

import json
Expand All @@ -29,6 +29,11 @@
#


class VendorUI(TypedDict, total=True):
logo_url: str # vendor logo url
strong_color: str # vendor main color


class Vendor(TypedDict, total=False):
"""
Brand information about the vendor
Expand All @@ -47,6 +52,8 @@ class Vendor(TypedDict, total=False):

release_notes_url_template: str # a template url where `{vtag}` will be replaced, eg: "http://example.com/{vtag}.md"

ui: VendorUI


class IssueTracker(TypedDict, total=True):
"""Link to actions in an online issue tracker (e.g. in fogbugz, github, gitlab ...)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
"""
Collection of functions that create fake raw data that can be used
to populate postgres DATABASE, create datasets with consistent values, etc
Collection of functions that create fake raw data that can be used
to populate postgres DATABASE, create datasets with consistent values, etc

Built on top of the idea of Faker library (https://faker.readthedocs.io/en/master/),
that generate fake data to bootstrap a database, fill-in stress tests, anonymize data ...
etc
Built on top of the idea of Faker library (https://faker.readthedocs.io/en/master/),
that generate fake data to bootstrap a database, fill-in stress tests, anonymize data ...
etc

NOTE: all outputs MUST be Dict-like or built-in data structures that fit at least
required fields in postgres_database.models tables or pydantic models.
NOTE: all outputs MUST be Dict-like or built-in data structures that fit at least
required fields in postgres_database.models tables or pydantic models.

NOTE: to reduce coupling, please import simcore_postgres_database inside of the functions
NOTE: to reduce coupling, please import simcore_postgres_database inside of the functions
"""

import itertools
Expand Down Expand Up @@ -232,7 +232,7 @@ def random_product(
- group_id: product group ID. SEE get_or_create_product_group to produce `group_id`
- registration_email_template
"""
from simcore_postgres_database.models.products import Vendor, products
from simcore_postgres_database.models.products import Vendor, VendorUI, products

name = overrides.get("name")
suffix = fake.unique.word() if name is None else name
Expand All @@ -257,6 +257,10 @@ def random_product(
invitation_url=fake.url(),
invitation_form=fake.boolean(),
address=fake.address().replace("\n", ". "),
ui=VendorUI(
logo_url=fake.url(),
strong_color=fake.color(),
),
),
"registration_email_template": registration_email_template,
"created": fake.date_time_this_decade(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,8 @@ qx.Class.define("osparc.auth.LoginWithDecorators", {
if (urlFragment.nav && urlFragment.nav.length) {
if (urlFragment.nav[0] === "registration") {
pages.setSelection([registration]);
} else if (urlFragment.nav[0] === "request-account" && requestAccount) {
pages.setSelection([requestAccount]);
} else if (urlFragment.nav[0] === "request-account") {
requestAccount ? pages.setSelection([requestAccount]) : pages.setSelection([registration]);
} else if (urlFragment.nav[0] === "reset-password") {
pages.setSelection([resetPassword]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class AttachmentTuple(NamedTuple):
payload: bytearray


async def _send_email_with_attachements(
async def _send_email_with_attachments(
*,
settings: SMTPSettings,
sender: str,
Expand All @@ -160,7 +160,7 @@ async def _send_email_with_attachements(
reply_to: str | None = None,
) -> MIMEMessage:
"""
Sends an email with a body/subject marked as html with file attachement/s
Sends an email with a body/subject marked as html with file attachment/s
"""
# NOTE: Intentionally separated from send_email to further optimize legacy code

Expand Down Expand Up @@ -240,7 +240,7 @@ async def send_email_from_template(
subject, body = _render_template(request, template, context)

if attachments:
return await _send_email_with_attachements(
return await _send_email_with_attachments(
settings=settings,
sender=from_,
recipient=to,
Expand Down
Loading
Loading