Voucher bulk creation: Add markdown preview for email field (#3143)

This commit is contained in:
Raphael Michel
2023-03-15 15:55:34 +01:00
committed by GitHub
parent 859004ec59
commit c9e5cce7d0
6 changed files with 123 additions and 11 deletions

View File

@@ -5,7 +5,7 @@
{% block title %}{% trans "Voucher" %}{% endblock %}
{% block inside %}
<h1>{% trans "Create multiple vouchers" %}</h1>
<form action="" method="post" class="form-horizontal" data-asynctask>
<form action="" method="post" class="form-horizontal" data-asynctask mail-preview-url="{% url "control:event.vouchers.bulk.mail_preview" event=request.event.slug organizer=request.event.organizer.slug %}">
{% csrf_token %}
{% bootstrap_form_errors form %}
<fieldset>
@@ -82,8 +82,54 @@
<fieldset>
<legend>{% trans "Send out emails" %}</legend>
{% bootstrap_field form.send layout="control" %}
{% bootstrap_field form.send_subject layout="horizontal" %}
{% bootstrap_field form.send_message layout="horizontal" %}
<div id="send_subject_panel" class="preview-panel form-group" for="send_subject">
{% with field=form.send_subject item="send_subject" %}
<label class="col-md-3 control-label">{{ field.label }}</label>
<div class="col-md-9">
<ul class="nav nav-tabs">
<li role="presentation" class="active">
<a data-toggle="tab" type="edit" href="#{{ item }}_edit"><i class="fa fa-pencil-square-o fa-fw"></i> {% trans "Edit" %}</a>
</li>
<li role="presentation">
<a data-toggle="tab" type="preview" href="#{{ item }}_preview"><i class="fa fa-tv fa-fw"></i> {% trans "Preview" %}</a>
</li>
</ul>
<div class="tab-content">
<div id="{{ item }}_edit" class="tab-pane fade in active">
{% bootstrap_field field show_label=False form_group_class="" %}
</div>
<div id="{{ item }}_preview" class="tab-pane mail-preview-group">
<div lang="all" for="{{ item }}" class="mail-preview"></div>
</div>
</div>
</div>
{% endwith %}
</div>
<div id="send_message_panel" class="preview-panel form-group" for="send_message">
{% with field=form.send_message item="send_message" %}
<label class="col-md-3 control-label">{{ field.label }}</label>
<div class="col-md-9">
<ul class="nav nav-tabs">
<li role="presentation" class="active">
<a data-toggle="tab" type="edit" href="#{{ item }}_edit"><i class="fa fa-pencil-square-o fa-fw"></i> {% trans "Edit" %}</a>
</li>
<li role="presentation">
<a data-toggle="tab" type="preview" href="#{{ item }}_preview"><i class="fa fa-tv fa-fw"></i> {% trans "Preview" %}</a>
</li>
</ul>
<div class="tab-content">
<div id="{{ item }}_edit" class="tab-pane fade in active">
{% bootstrap_field field show_label=False form_group_class="" %}
</div>
<div id="{{ item }}_preview" class="tab-pane mail-preview-group">
<div lang="all" for="{{ item }}" class="mail-preview"></div>
</div>
</div>
</div>
{% endwith %}
</div>
{% bootstrap_field form.send_recipients layout="horizontal" %}
</fieldset>
{% eventsignal request.event "pretix.control.signals.voucher_form_html" form=form %}

View File

@@ -324,6 +324,7 @@ urlpatterns = [
re_path(r'^vouchers/add$', vouchers.VoucherCreate.as_view(), name='event.vouchers.add'),
re_path(r'^vouchers/go$', vouchers.VoucherGo.as_view(), name='event.vouchers.go'),
re_path(r'^vouchers/bulk_add$', vouchers.VoucherBulkCreate.as_view(), name='event.vouchers.bulk'),
re_path(r'^vouchers/bulk_add/mail_preview$', vouchers.VoucherBulkMailPreview.as_view(), name='event.vouchers.bulk.mail_preview'),
re_path(r'^vouchers/bulk_action$', vouchers.VoucherBulkAction.as_view(), name='event.vouchers.bulkaction'),
re_path(r'^orders/(?P<code>[0-9A-Z]+)/transition$', orders.OrderTransition.as_view(),
name='event.order.transition'),

View File

@@ -712,8 +712,11 @@ class MailSettingsPreview(EventPermissionRequiredMixin, View):
ctx = {}
for p in get_available_placeholders(self.request.event, MailSettingsForm.base_context[item]).values():
s = str(p.render_sample(self.request.event))
if s.strip().startswith('*'):
ctx[p.identifier] = s
if s.strip().startswith('* '):
ctx[p.identifier] = '<div class="placeholder" title="{}">{}</div>'.format(
_('This value will be replaced based on dynamic parameters.'),
markdown_compile_email(s)
)
else:
ctx[p.identifier] = '<span class="placeholder" title="{}">{}</span>'.format(
_('This value will be replaced based on dynamic parameters.'),

View File

@@ -35,6 +35,7 @@
import io
import bleach
from defusedcsv import csv
from django.conf import settings
from django.contrib import messages
@@ -56,10 +57,12 @@ from django.views.generic import (
CreateView, ListView, TemplateView, UpdateView, View,
)
from pretix.base.email import get_available_placeholders
from pretix.base.models import CartPosition, LogEntry, Voucher
from pretix.base.models.vouchers import generate_codes
from pretix.base.services.locking import NoLockManager
from pretix.base.services.vouchers import vouchers_send
from pretix.base.templatetags.rich_text import markdown_compile_email
from pretix.base.views.tasks import AsyncFormView
from pretix.control.forms.filter import VoucherFilterForm, VoucherTagFilterForm
from pretix.control.forms.vouchers import VoucherBulkForm, VoucherForm
@@ -67,6 +70,7 @@ from pretix.control.permissions import EventPermissionRequiredMixin
from pretix.control.signals import voucher_form_class
from pretix.control.views import PaginationMixin
from pretix.helpers.compat import CompatDeleteView
from pretix.helpers.format import format_map
from pretix.helpers.models import modelcopy
@@ -509,6 +513,52 @@ class VoucherBulkCreate(EventPermissionRequiredMixin, AsyncFormView):
return super().form_invalid(form)
class VoucherBulkMailPreview(EventPermissionRequiredMixin, View):
permission = 'can_change_vouchers'
# return the origin text if key is missing in dict
class SafeDict(dict):
def __missing__(self, key):
return '{' + key + '}'
# get all supported placeholders with dummy values
def placeholders(self, item):
ctx = {}
base_ctx = ['event', 'name']
if item == 'send_message':
base_ctx += ['voucher_list']
for p in get_available_placeholders(self.request.event, base_ctx).values():
s = str(p.render_sample(self.request.event))
if s.strip().startswith('* ') or s.startswith(' '):
ctx[p.identifier] = '<div class="placeholder" title="{}">{}</div>'.format(
_('This value will be replaced based on dynamic parameters.'),
markdown_compile_email(s)
)
else:
ctx[p.identifier] = '<span class="placeholder" title="{}">{}</span>'.format(
_('This value will be replaced based on dynamic parameters.'),
s
)
return self.SafeDict(ctx)
def post(self, request, *args, **kwargs):
preview_item = request.POST.get('item', '')
if preview_item not in ('send_message', 'send_subject'):
return HttpResponseBadRequest(_('invalid item'))
msgs = {}
if "subject" in preview_item:
msgs["all"] = format_map(bleach.clean(request.POST.get(preview_item, "")), self.placeholders(preview_item))
else:
msgs["all"] = markdown_compile_email(
format_map(request.POST.get(preview_item), self.placeholders(preview_item))
)
return JsonResponse({
'item': preview_item,
'msgs': msgs
})
class VoucherRNG(EventPermissionRequiredMixin, View):
permission = 'can_change_vouchers'