-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Preview emails using the full page editor and standard email rendering (
#3778) Adds the full page markdown editor for emails along with iframed previews using the standard email rendering. As there are differences in email clients and browsers a test email still needs to be sent out, but at least the previews are isolated from the GC CSS/JS environment. <img width="2286" alt="Screenshot 2025-01-09 at 11 37 36" src="https://github.com/user-attachments/assets/cd82e12a-c77b-4412-8d3a-778fcbf61996" /> <img width="1199" alt="Screenshot 2025-01-09 at 11 37 56" src="https://github.com/user-attachments/assets/9a75c852-c24a-4604-9b6d-27079c0883fe" /> Closes #3682
- Loading branch information
Showing
14 changed files
with
333 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,27 @@ | ||
from django import forms | ||
|
||
from grandchallenge.core.forms import SaveFormInitMixin | ||
from grandchallenge.core.widgets import MarkdownEditorInlineWidget | ||
from grandchallenge.emails.models import Email | ||
from grandchallenge.emails.widgets import MarkdownEditorEmailFullPageWidget | ||
from grandchallenge.subdomains.utils import reverse | ||
|
||
|
||
class EmailForm(SaveFormInitMixin, forms.ModelForm): | ||
class EmailMetadataForm(SaveFormInitMixin, forms.ModelForm): | ||
class Meta: | ||
model = Email | ||
fields = ( | ||
"subject", | ||
"body", | ||
fields = ("subject",) | ||
|
||
|
||
class EmailBodyForm(SaveFormInitMixin, forms.ModelForm): | ||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
|
||
self.fields["body"].widget = MarkdownEditorEmailFullPageWidget( | ||
preview_url=reverse( | ||
"emails:rendered-detail", kwargs={"pk": self.instance.pk} | ||
) | ||
) | ||
widgets = {"body": MarkdownEditorInlineWidget} | ||
|
||
class Meta: | ||
model = Email | ||
fields = ("body",) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
app/grandchallenge/emails/static/js/emails/email_markdown_preview.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
document.addEventListener("DOMContentLoaded", event => { | ||
const iframes = document.querySelectorAll(".markdownx-preview"); | ||
for (const iframe of iframes) { | ||
const observer = new MutationObserver(() => { | ||
iframe.srcdoc = iframe.innerHTML; | ||
}); | ||
observer.observe(iframe, { | ||
childList: true, | ||
}); | ||
} | ||
}); |
17 changes: 17 additions & 0 deletions
17
app/grandchallenge/emails/templates/emails/email_body_update.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{% extends "emails/email_form.html" %} | ||
{% load crispy_forms_tags %} | ||
|
||
{% block container %}container-fluid{% endblock %} | ||
|
||
{% block content %} | ||
|
||
<h2>Update Email</h2> | ||
|
||
<div class="alert alert-warning ml-3" role="alert"> | ||
The body preview does not accurately represent how the result will be rendered in email applications! | ||
Always send out a test version to check the formatting. | ||
</div> | ||
|
||
{% crispy form %} | ||
|
||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
app/grandchallenge/emails/templates/emails/email_full_page_markdown_widget.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<div class="markdownx markdownx-full-page"> | ||
{% include "markdownx/partials/toolbar.html" %} | ||
<div class="row"> | ||
<div class="col-md-6"> | ||
<div id="editor-{{ widget.attrs.id }}" aria-labelledby="editor-panel-{{ widget.attrs.id }}"> | ||
{% include "markdownx/partials/textarea.html" %} | ||
</div> | ||
</div> | ||
<div class="col-md-6"> | ||
<div id="preview-{{ widget.attrs.id }}" aria-labelledby="preview-panel-{{ widget.attrs.id }}"> | ||
<iframe class="markdownx-preview w-100" sandbox=""></iframe> | ||
</div> | ||
</div> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
app/grandchallenge/emails/templates/emails/email_rendered_detail.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{{ object.rendered_body }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from grandchallenge.core.widgets import MarkdownEditorFullPageWidget | ||
|
||
|
||
class MarkdownEditorEmailFullPageWidget(MarkdownEditorFullPageWidget): | ||
template_name = "emails/email_full_page_markdown_widget.html" | ||
|
||
def __init__(self, *args, preview_url, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.preview_url = preview_url | ||
|
||
def add_markdownx_attrs(self, *args, **kwargs): | ||
attrs = super().add_markdownx_attrs(*args, **kwargs) | ||
attrs.update( | ||
{ | ||
"data-markdownx-urls-path": self.preview_url, | ||
} | ||
) | ||
return attrs | ||
|
||
class Media: | ||
js = [ | ||
"js/emails/email_markdown_preview.mjs", | ||
] |
Oops, something went wrong.