Allow adding broadcast templates

At the moment the page is the same as for text message templates,
except:
- different H1
- no guidance about personalisation, links, etc (until we decide how
  these should work)

For now you won’t be able to really create a broadcast template, because
the API doesn’t support it (the API will respond with a 400). But that’s
OK because no real services have the broadcast permission yet.

This required a bit of refactoring of how we check which template types
a service can use, because there were some hard-coded assumptions about
emails and text messages.
This commit is contained in:
Chris Hill-Scott
2020-07-01 16:43:08 +01:00
parent 8a1d86633c
commit 154d4bdb85
11 changed files with 175 additions and 77 deletions

View File

@@ -780,6 +780,10 @@ class SMSTemplateForm(BaseTemplateForm):
OnlySMSCharacters()(None, field)
class BroadcastTemplateForm(SMSTemplateForm):
pass
class LetterAddressForm(StripWhitespaceForm):
def __init__(self, *args, allow_international_letters=False, **kwargs):
@@ -1644,7 +1648,7 @@ class TemplateAndFoldersSelectionForm(Form):
self,
all_template_folders,
template_list,
allow_adding_letter_template,
available_template_types,
allow_adding_copy_of_template,
*args,
**kwargs
@@ -1652,6 +1656,8 @@ class TemplateAndFoldersSelectionForm(Form):
super().__init__(*args, **kwargs)
self.available_template_types = available_template_types
self.templates_and_folders.choices = template_list.as_id_and_name
self.op = None
@@ -1664,12 +1670,25 @@ class TemplateAndFoldersSelectionForm(Form):
]
self.add_template_by_template_type.choices = list(filter(None, [
# We want to show email and text message to everyone,
# whether or not the service has them switched on. The
# option to add letter or broadcast templates should only
# be shown to services which have that permission
('email', 'Email'),
('sms', 'Text message'),
('letter', 'Letter') if allow_adding_letter_template else None,
('letter', 'Letter') if 'letter' in available_template_types else None,
('broadcast', 'Broadcast') if 'broadcast' in available_template_types else None,
('copy-existing', 'Copy an existing template') if allow_adding_copy_of_template else None,
]))
@property
def trying_to_add_unavailable_template_type(self):
return all((
self.is_add_template_op,
self.add_template_by_template_type.data,
self.add_template_by_template_type.data not in self.available_template_types,
))
def is_selected(self, template_folder_id):
return template_folder_id in (self.templates_and_folders.data or [])

View File

@@ -53,7 +53,6 @@ from app.template_previews import TemplatePreview, get_page_count_for_letter
from app.utils import (
PermanentRedirect,
Spreadsheet,
email_or_sms_not_enabled,
get_errors_for_csv,
get_help_argument,
get_template,
@@ -128,7 +127,7 @@ def send_messages(service_id, template_id):
elif db_template['template_type'] == 'sms':
sms_sender = get_sms_sender_from_session()
if email_or_sms_not_enabled(db_template['template_type'], current_service.permissions):
if db_template['template_type'] not in current_service.available_template_types:
return redirect(url_for(
'.action_blocked',
service_id=service_id,
@@ -302,8 +301,11 @@ def send_test(service_id, template_id):
db_template = current_service.get_template_with_user_permission_or_403(template_id, current_user)
if db_template['template_type'] == 'letter':
session['sender_id'] = None
return redirect(
url_for('.send_one_off_letter_address', service_id=service_id, template_id=template_id)
)
if email_or_sms_not_enabled(db_template['template_type'], current_service.permissions):
if db_template['template_type'] not in current_service.available_template_types:
return redirect(url_for(
'.action_blocked',
service_id=service_id,
@@ -311,11 +313,6 @@ def send_test(service_id, template_id):
return_to='view_template',
template_id=template_id))
if db_template['template_type'] == 'letter':
return redirect(
url_for('.send_one_off_letter_address', service_id=service_id, template_id=template_id)
)
return redirect(url_for(
{
'main.send_test': '.send_test_step',

View File

@@ -16,6 +16,7 @@ from app import (
)
from app.main import main, no_cookie
from app.main.forms import (
BroadcastTemplateForm,
EmailTemplateForm,
LetterTemplateForm,
LetterTemplatePostageForm,
@@ -30,7 +31,6 @@ from app.models.service import Service
from app.models.template_list import TemplateList, TemplateLists
from app.template_previews import TemplatePreview, get_page_count_for_letter
from app.utils import (
email_or_sms_not_enabled,
get_template,
should_skip_template_page,
user_has_permissions,
@@ -40,7 +40,8 @@ from app.utils import (
form_objects = {
'email': EmailTemplateForm,
'sms': SMSTemplateForm,
'letter': LetterTemplateForm
'letter': LetterTemplateForm,
'broadcast': BroadcastTemplateForm,
}
@@ -122,7 +123,7 @@ def choose_template(service_id, template_type='all', template_folder_id=None):
all_template_folders=current_service.get_user_template_folders(current_user),
template_list=template_list,
template_type=template_type,
allow_adding_letter_template=current_service.has_permission('letter'),
available_template_types=current_service.available_template_types,
allow_adding_copy_of_template=(
current_service.all_templates or len(current_user.service_ids) > 1
),
@@ -136,6 +137,13 @@ def choose_template(service_id, template_type='all', template_folder_id=None):
return process_folder_management_form(templates_and_folders_form, template_folder_id)
except HTTPError as e:
flash(e.message)
elif templates_and_folders_form.trying_to_add_unavailable_template_type:
return redirect(url_for(
'.action_blocked',
service_id=current_service.id,
notification_type=templates_and_folders_form.add_template_by_template_type.data,
return_to='add_new_template',
))
if 'templates_and_folders' in templates_and_folders_form.errors:
flash('Select at least one template or folder')
@@ -199,6 +207,7 @@ def get_template_nav_label(value):
'sms': 'Text message',
'email': 'Email',
'letter': 'Letter',
'broadcast': 'Broadcast',
}[value]
@@ -310,20 +319,12 @@ def _add_template_by_type(template_type, template_folder_id):
template_id=blank_letter['data']['id'],
))
if email_or_sms_not_enabled(template_type, current_service.permissions):
return redirect(url_for(
'.action_blocked',
service_id=current_service.id,
notification_type=template_type,
return_to='add_new_template',
))
else:
return redirect(url_for(
'.add_service_template',
service_id=current_service.id,
template_type=template_type,
template_folder_id=template_folder_id,
))
return redirect(url_for(
'.add_service_template',
service_id=current_service.id,
template_type=template_type,
template_folder_id=template_folder_id,
))
@main.route("/services/<uuid:service_id>/templates/copy")
@@ -437,7 +438,7 @@ def action_blocked(service_id, notification_type, return_to, template_id=None):
service_id=service_id,
notification_type=notification_type,
back_link=back_link(),
)
), 403
@main.route("/services/<uuid:service_id>/templates/folders/<uuid:template_folder_id>/manage", methods=['GET', 'POST'])
@@ -527,8 +528,14 @@ def delete_template_folder(service_id, template_folder_id):
@user_has_permissions('manage_templates')
def add_service_template(service_id, template_type, template_folder_id=None):
if not current_service.has_permission('letter') and template_type == 'letter':
abort(403)
if template_type not in current_service.available_template_types:
return redirect(url_for(
'.action_blocked',
service_id=service_id,
notification_type=template_type,
template_folder_id=template_folder_id,
return_to='templates',
))
form = form_objects[template_type]()
if form.validate_on_submit():
@@ -558,22 +565,13 @@ def add_service_template(service_id, template_type, template_folder_id=None):
url_for('.view_template', service_id=service_id, template_id=new_template['data']['id'])
)
if email_or_sms_not_enabled(template_type, current_service.permissions):
return redirect(url_for(
'.action_blocked',
service_id=service_id,
notification_type=template_type,
template_folder_id=template_folder_id,
return_to='templates',
))
else:
return render_template(
'views/edit-{}-template.html'.format(template_type),
form=form,
template_type=template_type,
template_folder_id=template_folder_id,
heading_action='New',
)
return render_template(
'views/edit-{}-template.html'.format(template_type),
form=form,
template_type=template_type,
template_folder_id=template_folder_id,
heading_action='New',
)
def abort_403_if_not_admin_user():
@@ -642,7 +640,7 @@ def edit_service_template(service_id, template_id):
template_id=template_id
))
if email_or_sms_not_enabled(template['template_type'], current_service.permissions):
if template['template_type'] not in current_service.available_template_types:
return redirect(url_for(
'.action_blocked',
service_id=service_id,

View File

@@ -54,6 +54,7 @@ class Service(JSONModel):
'email',
'sms',
'letter',
'broadcast',
)
ALL_PERMISSIONS = TEMPLATE_TYPES + (

View File

@@ -24,6 +24,12 @@
{%- else -%}
letters
{%- endif -%}
{%- elif template_type == 'broadcast' -%}
{%- if count == 1 -%}
broadcast
{%- else -%}
broadcasts
{%- endif -%}
{%- endif %} {{ suffix }}
{%- endmacro %}

View File

@@ -0,0 +1,31 @@
{% extends "withnav_template.html" %}
{% from "components/textbox.html" import textbox %}
{% from "components/page-header.html" import page_header %}
{% from "components/page-footer.html" import sticky_page_footer %}
{% from "components/form.html" import form_wrapper %}
{% block service_page_title %}
{{ heading_action }} broadcast template
{% endblock %}
{% block maincolumn_content %}
{{ page_header(
'{} broadcast template'.format(heading_action),
back_link=url_for('main.view_template', service_id=current_service.id, template_id=template.id) if template else url_for('main.choose_template', service_id=current_service.id, template_folder_id=template_folder_id)
) }}
{% call form_wrapper() %}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
{{ textbox(form.name, width='1-1', hint='Your recipients will not see this') }}
</div>
<div class="govuk-grid-column-two-thirds">
{{ textbox(form.template_content, highlight_placeholders=True, width='1-1', rows=5) }}
{{ sticky_page_footer('Save') }}
</div>
</div>
{% endcall %}
{% endblock %}

View File

@@ -5,11 +5,12 @@ from app.models.feedback import (
PROBLEM_TICKET_TYPE,
QUESTION_TICKET_TYPE,
)
from app.models.service import Service
class TemplateTypeConverter(BaseConverter):
regex = '(?:email|sms|letter)'
regex = '(?:{})'.format('|'.join(Service.TEMPLATE_TYPES))
class TicketTypeConverter(BaseConverter):

View File

@@ -461,10 +461,6 @@ def get_time_left(created_at, service_data_retention_days=7):
)
def email_or_sms_not_enabled(template_type, permissions):
return (template_type in ['email', 'sms']) and (template_type not in permissions)
def get_logo_cdn_domain():
parsed_uri = urlparse(current_app.config['ADMIN_BASE_URL'])