mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-02-05 10:53:28 -05:00
Preview service name when adding a new service
This commit adds a new page, which appears after a user enters the name for their new service. It shows how the service name will appear in emails and text messages. This means that the new service is not created until after they have confirmed that the name is appropriate in context. This has also involved: - visual changes to the ‘email template’ pattern, which wasn’t very refined before - removing a bunch of words from the enter service name page, because most users don’t read them, and we reckon that showing a preview is a better way of getting them to understand what is meant by service name Still to do: - validating the the generated email address for a service is unique (on the API) side - having the API return the generated email address, rather than determining it in the admin app
This commit is contained in:
@@ -1,11 +1,17 @@
|
||||
.column-one-quarter {
|
||||
@include grid-column(1/4);
|
||||
}
|
||||
|
||||
.column-three-quarters {
|
||||
@include grid-column(3/4);
|
||||
}
|
||||
|
||||
|
||||
.column-one-eighth {
|
||||
@include grid-column(1/8);
|
||||
}
|
||||
|
||||
.column-seven-eighths {
|
||||
@include grid-column(7/8);
|
||||
}
|
||||
|
||||
.bottom-gutter {
|
||||
margin-bottom: $gutter;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
@@ -1,24 +1,30 @@
|
||||
.email-message {
|
||||
|
||||
margin-bottom: $gutter;
|
||||
border: 1px solid $border-colour;
|
||||
|
||||
&-subject {
|
||||
@include bold-19;
|
||||
border-bottom: 1px solid $border-colour;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
&-body {
|
||||
border-bottom: 1px solid $white;
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
max-height: 103px;
|
||||
}
|
||||
|
||||
&-name {
|
||||
@include bold-19;
|
||||
margin: 50px 0 10px 0;
|
||||
margin: 20px 0 10px 0;
|
||||
}
|
||||
|
||||
&-subject,
|
||||
&-from {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
&-from {
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid $border-colour;
|
||||
}
|
||||
|
||||
&-body {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: $gutter-half 0 0 0;
|
||||
margin: 0 0 $gutter 0;
|
||||
clear: both;
|
||||
border-top: 1px solid $border-colour;
|
||||
border-bottom: 1px solid $border-colour;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
border-radius: 5px;
|
||||
white-space: normal;
|
||||
margin: 0 0 $gutter 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.sms-message-wrapper-with-radio {
|
||||
@@ -53,3 +54,8 @@
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.sms-message-from {
|
||||
@include bold-19;
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -85,3 +85,7 @@
|
||||
.textbox-help-link {
|
||||
margin: 5px 0 0 0;
|
||||
}
|
||||
|
||||
.textbox-right-aligned {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from flask import url_for
|
||||
from app import notifications_api_client
|
||||
from notifications_python_client.errors import HTTPError
|
||||
from app.utils import BrowsableItem
|
||||
|
||||
|
||||
@@ -26,6 +27,16 @@ def get_service_by_id(id_):
|
||||
return notifications_api_client.get_service(id_)
|
||||
|
||||
|
||||
def get_service_by_id_or_404(id_):
|
||||
try:
|
||||
return get_service_by_id(id_)
|
||||
except HTTPError as e:
|
||||
if e.status_code == 404:
|
||||
abort(404)
|
||||
else:
|
||||
raise e
|
||||
|
||||
|
||||
def get_services(user_id=None):
|
||||
if user_id:
|
||||
return notifications_api_client.get_services({'user_id': str(user_id)})
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
from flask import render_template, redirect, session, url_for
|
||||
import re
|
||||
|
||||
from flask import render_template, request, redirect, session, url_for
|
||||
from flask_login import login_required, current_user
|
||||
from app.main import main
|
||||
from app.main.dao import services_dao, users_dao
|
||||
@@ -15,13 +17,33 @@ def add_service():
|
||||
else:
|
||||
heading = 'Add a new service'
|
||||
if form.validate_on_submit():
|
||||
user = users_dao.get_user_by_id(session['user_id'])
|
||||
service_id = services_dao.insert_new_service(form.name.data, user.id)
|
||||
session['service_name'] = form.name.data
|
||||
return redirect(url_for('main.service_dashboard', service_id=service_id))
|
||||
return redirect(url_for('main.add_from_address'))
|
||||
else:
|
||||
return render_template(
|
||||
'views/add-service.html',
|
||||
form=form,
|
||||
heading=heading
|
||||
)
|
||||
|
||||
|
||||
@main.route("/confirm-add-service", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_from_address():
|
||||
if request.method == 'POST':
|
||||
user = users_dao.get_user_by_id(session['user_id'])
|
||||
service_id = services_dao.insert_new_service(session['service_name'], user.id)
|
||||
return redirect(url_for('main.service_dashboard', service_id=service_id))
|
||||
else:
|
||||
return render_template(
|
||||
'views/add-from-address.html',
|
||||
service_name=session['service_name'],
|
||||
from_address="{}@notifications.service.gov.uk".format(_email_safe(session['service_name']))
|
||||
)
|
||||
|
||||
|
||||
def _email_safe(string):
|
||||
return "".join([
|
||||
character.lower() if character.isalnum() or character == "." else ""
|
||||
for character in re.sub("\s+", ".", string.strip())
|
||||
])
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% macro email_message(subject, body, name=None, edit_link=None) %}
|
||||
{% macro email_message(subject, body, name=None, edit_link=None, from_name=None, from_address=None) %}
|
||||
{% if name %}
|
||||
<h3 class="email-message-name">
|
||||
{% if edit_link %}
|
||||
@@ -9,9 +9,30 @@
|
||||
</h3>
|
||||
{% endif %}
|
||||
<div class="email-message">
|
||||
<div class="email-message-subject">
|
||||
{{ subject }}
|
||||
</div>
|
||||
{% if from_name and from_address %}
|
||||
<div class="email-message-from">
|
||||
<div class="grid-row">
|
||||
<div class="column-one-eighth">
|
||||
<span class="form-hint">From</span>
|
||||
</div>
|
||||
<div class="column-seven-eighths">
|
||||
{{ from_name }} <{{ from_address }}>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if subject %}
|
||||
<div class="email-message-subject">
|
||||
<div class="grid-row">
|
||||
<div class="column-one-eighth">
|
||||
<span class="form-hint">Subject</span>
|
||||
</div>
|
||||
<div class="column-seven-eighths">
|
||||
{{ subject }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="email-message-body">
|
||||
{{ body|nl2br }}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% macro sms_message(
|
||||
body, recipient=None, name=None, id=None, edit_link=None
|
||||
body, recipient=None, name=None, id=None, edit_link=None, from=None
|
||||
) %}
|
||||
{% if name %}
|
||||
<h3 class="sms-message-name">
|
||||
@@ -11,6 +11,11 @@
|
||||
</h3>
|
||||
{% endif %}
|
||||
<div class="sms-message-wrapper{% if input_name %}-with-radio{% endif %}">
|
||||
{% if from %}
|
||||
<span class="sms-message-from">
|
||||
{{ from }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{{ body }}
|
||||
</div>
|
||||
{% if recipient %}
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
autofocus=False,
|
||||
help_link=None,
|
||||
help_link_text=None,
|
||||
width='2-3'
|
||||
width='2-3',
|
||||
suffix=None
|
||||
) %}
|
||||
<div class="form-group{% if field.errors %} error{% endif %}" {% if autofocus %}data-module="autofocus"{% endif %}>
|
||||
<label class="form-label" for="{{ field.name }}">
|
||||
@@ -22,9 +23,12 @@
|
||||
{% endif %}
|
||||
</label>
|
||||
{{ field(**{
|
||||
'class': 'form-control form-control-{} textbox-highlight-textbox'.format(width) if highlight_tags else 'form-control form-control-{}'.format(width),
|
||||
'class': 'form-control form-control-{} textbox-highlight-textbox'.format(width) if highlight_tags else 'form-control form-control-{} {}'.format(width, 'textbox-right-aligned' if suffix else ''),
|
||||
'data-module': 'highlight-tags' if highlight_tags else ''
|
||||
}) }}
|
||||
{% if suffix %}
|
||||
<span>{{ suffix }}</span>
|
||||
{% endif %}
|
||||
{% if help_link and help_link_text %}
|
||||
<p class="textbox-help-link">
|
||||
<a href='{{ help_link }}'>{{ help_link_text }}</a>
|
||||
|
||||
42
app/templates/views/add-from-address.html
Normal file
42
app/templates/views/add-from-address.html
Normal file
@@ -0,0 +1,42 @@
|
||||
{% extends "withoutnav_template.html" %}
|
||||
{% from "components/textbox.html" import textbox %}
|
||||
{% from "components/page-footer.html" import page_footer %}
|
||||
{% from "components/sms-message.html" import sms_message %}
|
||||
{% from "components/email-message.html" import email_message %}
|
||||
|
||||
{% block page_title %}
|
||||
Preview your service name – GOV.UK Notify
|
||||
{% endblock %}
|
||||
|
||||
{% block maincolumn_content %}
|
||||
|
||||
<h1 class="heading-large">
|
||||
Preview your service name
|
||||
</h1>
|
||||
|
||||
<div class="grid-row">
|
||||
<div class="column-two-thirds">
|
||||
{{ sms_message(
|
||||
"{}: we received your payment, thank you".format(service_name),
|
||||
name="Text message",
|
||||
recipient='Sent from 40604'
|
||||
) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-row">
|
||||
<div class='column-two-thirds'>
|
||||
{{ email_message(
|
||||
subject="We received your payment, thank you",
|
||||
body="Dear Alice Smith,\n\nThank you for…",
|
||||
from_name=service_name,
|
||||
from_address=from_address,
|
||||
name="Email",
|
||||
) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="post">
|
||||
{{page_footer('Looks good', back_link=url_for(".add_service"))}}
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
@@ -12,27 +12,21 @@
|
||||
<div class="column-two-thirds">
|
||||
|
||||
<h1 class="heading-large">
|
||||
{{ heading }}
|
||||
When people receive notifications, who should they be from?
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
Users will see your service name when they receive messages through GOV.UK
|
||||
Notify:
|
||||
Be specific. Remember that there might be other people in your
|
||||
organisation using GOV.UK Notify.
|
||||
</p>
|
||||
|
||||
<ul class="list-bullet bottom-gutter">
|
||||
<li>
|
||||
at the start of every text message, eg ‘Vehicle tax: we received your
|
||||
payment, thank you’
|
||||
</li>
|
||||
<li>
|
||||
as your email sender name
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<form autocomplete="off" method="post">
|
||||
|
||||
{{ textbox(form.name, hint="You can change this later") }}
|
||||
|
||||
|
||||
{{ page_footer('Continue') }}
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -17,13 +17,14 @@ def test_get_should_render_add_service_template(app_,
|
||||
assert 'Add a new service' in response.get_data(as_text=True)
|
||||
|
||||
|
||||
def test_should_add_service_and_redirect_to_next_page(app_,
|
||||
mock_login,
|
||||
mock_create_service,
|
||||
mock_get_services,
|
||||
api_user_active,
|
||||
mock_get_user,
|
||||
mock_get_user_by_email):
|
||||
def test_should_add_service_and_redirect_to_next_page(
|
||||
app_,
|
||||
mock_login,
|
||||
mock_get_services,
|
||||
api_user_active,
|
||||
mock_get_user,
|
||||
mock_get_user_by_email
|
||||
):
|
||||
with app_.test_request_context():
|
||||
with app_.test_client() as client:
|
||||
client.login(api_user_active)
|
||||
@@ -31,6 +32,45 @@ def test_should_add_service_and_redirect_to_next_page(app_,
|
||||
url_for('main.add_service'),
|
||||
data={'name': 'testing the post'})
|
||||
assert response.status_code == 302
|
||||
assert response.location == url_for('main.add_from_address', _external=True)
|
||||
|
||||
|
||||
def test_should_confirm_add_service(
|
||||
app_,
|
||||
mock_login,
|
||||
mock_get_services,
|
||||
api_user_active,
|
||||
mock_get_user,
|
||||
mock_get_user_by_email
|
||||
):
|
||||
with app_.test_request_context():
|
||||
with app_.test_client() as client:
|
||||
client.login(api_user_active)
|
||||
with client.session_transaction() as session:
|
||||
session['service_name'] = 'Renew Your Pet Passport'
|
||||
response = client.get(url_for('main.add_from_address'))
|
||||
assert response.status_code == 200
|
||||
assert 'Preview your service name' in response.get_data(as_text=True)
|
||||
assert 'Renew Your Pet Passport' in response.get_data(as_text=True)
|
||||
assert 'renew.your.pet.passport@notifications.service.gov.uk' in response.get_data(as_text=True)
|
||||
|
||||
|
||||
def test_should_add_service_after_confirmation(
|
||||
app_,
|
||||
mock_login,
|
||||
mock_create_service,
|
||||
mock_get_services,
|
||||
api_user_active,
|
||||
mock_get_user,
|
||||
mock_get_user_by_email
|
||||
):
|
||||
with app_.test_request_context():
|
||||
with app_.test_client() as client:
|
||||
client.login(api_user_active)
|
||||
with client.session_transaction() as session:
|
||||
session['service_name'] = 'Renew Your Pet Passport'
|
||||
response = client.post(url_for('main.add_from_address'))
|
||||
assert response.status_code == 302
|
||||
assert response.location == url_for('main.service_dashboard', service_id=101, _external=True)
|
||||
assert mock_create_service.called
|
||||
assert mock_get_services.called
|
||||
|
||||
Reference in New Issue
Block a user