mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-25 00:33:58 -04:00
Merge pull request #150 from alphagov/send-text-flow-revised
Send text flow revised
This commit is contained in:
BIN
app/assets/images/icon-important-2x.png
Normal file
BIN
app/assets/images/icon-important-2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 918 B |
@@ -38,3 +38,11 @@ a:visited {
|
|||||||
width: 5em;
|
width: 5em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.column-main {
|
||||||
|
|
||||||
|
> .heading-large {
|
||||||
|
margin-top: $gutter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,10 +10,12 @@
|
|||||||
margin: $gutter-half 0 $gutter 0;
|
margin: $gutter-half 0 $gutter 0;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
clear: both;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.banner-with-tick {
|
.banner-with-tick,
|
||||||
|
.banner-default-with-tick {
|
||||||
|
|
||||||
@extend %banner;
|
@extend %banner;
|
||||||
padding: $gutter-half ($gutter + $gutter-half);
|
padding: $gutter-half ($gutter + $gutter-half);
|
||||||
@@ -75,4 +77,19 @@
|
|||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
list-style-type: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner-important {
|
||||||
|
@extend %banner;
|
||||||
|
background: $white;
|
||||||
|
color: $text-colour;
|
||||||
|
background-image: file-url("icon-important-2x.png");
|
||||||
|
background-size: 34px 34px;
|
||||||
|
background-position: 0 0;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
padding: 7px 0 5px 50px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
&-filename {
|
&-filename {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding-left: $gutter-half;
|
padding-left: $gutter-half;
|
||||||
|
@include bold-19;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
margin-bottom: 50px;
|
margin-bottom: 50px;
|
||||||
|
|
||||||
&-back-link {
|
&-back-link {
|
||||||
display: block;
|
@include button($grey-1);
|
||||||
margin-top: $gutter;
|
display: inline-block;
|
||||||
|
padding: 0.52632em 0.78947em 0.26316em 0.78947em;
|
||||||
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-delete-link {
|
&-delete-link {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
.sms-message-name {
|
.sms-message-name {
|
||||||
@include bold-19;
|
@include bold-19;
|
||||||
margin: 30px 0 10px 0;
|
margin: 20px 0 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sms-message-picker {
|
.sms-message-picker {
|
||||||
@@ -61,3 +61,8 @@ label.sms-message-option {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sms-message-use-link {
|
||||||
|
margin-top: 70px;
|
||||||
|
@include bold-19;
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
.table-heading {
|
.table-heading {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
margin: 40px 0 5px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
%table-field,
|
%table-field,
|
||||||
@@ -56,7 +57,6 @@
|
|||||||
.table-empty-message {
|
.table-empty-message {
|
||||||
@include core-16;
|
@include core-16;
|
||||||
color: $secondary-text-colour;
|
color: $secondary-text-colour;
|
||||||
border-top: 1px solid $border-colour;
|
|
||||||
border-bottom: 1px solid $border-colour;
|
border-bottom: 1px solid $border-colour;
|
||||||
padding: 0.75em 0 0.5625em 0;
|
padding: 0.75em 0 0.5625em 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Path to assets for use with file-url()
|
||||||
|
$path: '/static/images/';
|
||||||
|
|
||||||
// Dependencies from GOV.UK Frontend Toolkit
|
// Dependencies from GOV.UK Frontend Toolkit
|
||||||
// https://github.com/alphagov/govuk_frontend_toolkit/
|
// https://github.com/alphagov/govuk_frontend_toolkit/
|
||||||
@import 'conditionals';
|
@import 'conditionals';
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ class ChangePasswordForm(Form):
|
|||||||
|
|
||||||
|
|
||||||
class CsvUploadForm(Form):
|
class CsvUploadForm(Form):
|
||||||
file = FileField('Upload a CSV file to add your recipients’ details', validators=[DataRequired(
|
file = FileField('Add recipients', validators=[DataRequired(
|
||||||
message='Please pick a file'), CsvFileValidator()])
|
message='Please pick a file'), CsvFileValidator()])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ from app.main.forms import AddServiceForm
|
|||||||
def add_service():
|
def add_service():
|
||||||
form = AddServiceForm(services_dao.find_all_service_names)
|
form = AddServiceForm(services_dao.find_all_service_names)
|
||||||
services = services_dao.get_services(current_user.id)
|
services = services_dao.get_services(current_user.id)
|
||||||
if len(services) == 0:
|
if len(services['data']) == 0:
|
||||||
heading = 'Set up notifications for your service'
|
heading = 'Which service do you want to set up notifications for?'
|
||||||
else:
|
else:
|
||||||
heading = 'Add a new service'
|
heading = 'Add a new service'
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from app.main import main
|
|||||||
from app.main.dao.services_dao import get_service_by_id
|
from app.main.dao.services_dao import get_service_by_id
|
||||||
from app.main.dao import templates_dao
|
from app.main.dao import templates_dao
|
||||||
from client.errors import HTTPError
|
from client.errors import HTTPError
|
||||||
from ._jobs import jobs
|
from app import job_api_client
|
||||||
|
|
||||||
|
|
||||||
@main.route("/services/<service_id>/dashboard")
|
@main.route("/services/<service_id>/dashboard")
|
||||||
@@ -12,6 +12,7 @@ from ._jobs import jobs
|
|||||||
def service_dashboard(service_id):
|
def service_dashboard(service_id):
|
||||||
try:
|
try:
|
||||||
templates = templates_dao.get_service_templates(service_id)['data']
|
templates = templates_dao.get_service_templates(service_id)['data']
|
||||||
|
jobs = job_api_client.get_job(service_id)['data']
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
if e.status_code == 404:
|
if e.status_code == 404:
|
||||||
abort(404)
|
abort(404)
|
||||||
@@ -27,8 +28,8 @@ def service_dashboard(service_id):
|
|||||||
raise e
|
raise e
|
||||||
return render_template(
|
return render_template(
|
||||||
'views/service_dashboard.html',
|
'views/service_dashboard.html',
|
||||||
jobs=jobs,
|
jobs=list(reversed(jobs)),
|
||||||
free_text_messages_remaining='25,000',
|
free_text_messages_remaining='250,000',
|
||||||
spent_this_month='0.00',
|
spent_this_month='0.00',
|
||||||
template_count=len(templates),
|
template_count=len(templates),
|
||||||
service_id=str(service_id))
|
service_id=str(service_id))
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from client.errors import HTTPError
|
|||||||
|
|
||||||
from app import job_api_client
|
from app import job_api_client
|
||||||
from app.main import main
|
from app.main import main
|
||||||
|
from app.main.dao import templates_dao
|
||||||
|
|
||||||
now = time.strftime('%H:%M')
|
now = time.strftime('%H:%M')
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ def view_jobs(service_id):
|
|||||||
def view_job(service_id, job_id):
|
def view_job(service_id, job_id):
|
||||||
try:
|
try:
|
||||||
job = job_api_client.get_job(service_id, job_id)['data']
|
job = job_api_client.get_job(service_id, job_id)['data']
|
||||||
|
template = templates_dao.get_service_template(service_id, job['template'])['data']
|
||||||
messages = []
|
messages = []
|
||||||
return render_template(
|
return render_template(
|
||||||
'views/job.html',
|
'views/job.html',
|
||||||
@@ -53,8 +55,7 @@ def view_job(service_id, job_id):
|
|||||||
cost=u'£0.00',
|
cost=u'£0.00',
|
||||||
uploaded_file_name=job['original_file_name'],
|
uploaded_file_name=job['original_file_name'],
|
||||||
uploaded_file_time=job['created_at'],
|
uploaded_file_time=job['created_at'],
|
||||||
template_used=job['template'],
|
template=template,
|
||||||
flash_message="We’ve accepted {} for processing".format(job['original_file_name']),
|
|
||||||
service_id=service_id
|
service_id=service_id
|
||||||
)
|
)
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
|
|||||||
@@ -32,13 +32,8 @@ from app.main.utils import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@main.route("/services/<service_id>/sms/send", methods=['GET', 'POST'])
|
@main.route("/services/<service_id>/sms/send", methods=['GET'])
|
||||||
def choose_sms_template(service_id):
|
def choose_sms_template(service_id):
|
||||||
if request.method == 'POST':
|
|
||||||
return redirect(url_for('.send_sms',
|
|
||||||
service_id=service_id,
|
|
||||||
template_id=request.form.get('template')))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
templates = templates_dao.get_service_templates(service_id)['data']
|
templates = templates_dao.get_service_templates(service_id)['data']
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
@@ -103,6 +98,7 @@ def check_sms(service_id, upload_id):
|
|||||||
'views/check-sms.html',
|
'views/check-sms.html',
|
||||||
upload_result=upload_result,
|
upload_result=upload_result,
|
||||||
message_template=template['content'],
|
message_template=template['content'],
|
||||||
|
original_file_name=original_file_name,
|
||||||
template_id=template_id,
|
template_id=template_id,
|
||||||
service_id=service_id
|
service_id=service_id
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from flask_login import login_required
|
|||||||
|
|
||||||
from app.main import main
|
from app.main import main
|
||||||
from app.main.forms import TemplateForm
|
from app.main.forms import TemplateForm
|
||||||
|
from app import job_api_client
|
||||||
from app.main.dao.services_dao import get_service_by_id
|
from app.main.dao.services_dao import get_service_by_id
|
||||||
from app.main.dao import templates_dao as tdao
|
from app.main.dao import templates_dao as tdao
|
||||||
from app.main.dao import services_dao as sdao
|
from app.main.dao import services_dao as sdao
|
||||||
@@ -13,6 +14,7 @@ from client.errors import HTTPError
|
|||||||
@login_required
|
@login_required
|
||||||
def manage_service_templates(service_id):
|
def manage_service_templates(service_id):
|
||||||
try:
|
try:
|
||||||
|
jobs = job_api_client.get_job(service_id)['data']
|
||||||
templates = tdao.get_service_templates(service_id)['data']
|
templates = tdao.get_service_templates(service_id)['data']
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
if e.status_code == 404:
|
if e.status_code == 404:
|
||||||
@@ -22,6 +24,7 @@ def manage_service_templates(service_id):
|
|||||||
return render_template(
|
return render_template(
|
||||||
'views/manage-templates.html',
|
'views/manage-templates.html',
|
||||||
service_id=service_id,
|
service_id=service_id,
|
||||||
|
has_jobs=bool(jobs),
|
||||||
templates=[tdao.TemplatesBrowsableItem(x) for x in templates])
|
templates=[tdao.TemplatesBrowsableItem(x) for x in templates])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{% macro file_upload(field) %}
|
{% macro file_upload(field, button_text="Choose file") %}
|
||||||
<div class="form-group{% if field.errors %} error{% endif %}" data-module="file-upload">
|
<div class="form-group{% if field.errors %} error{% endif %}" data-module="file-upload">
|
||||||
<label class="file-upload-label" for="{{ field.name }}">
|
<label class="file-upload-label" for="{{ field.name }}">
|
||||||
{{ field.label }}
|
{{ field.label }}
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
'class': 'file-upload-field'
|
'class': 'file-upload-field'
|
||||||
}) }}
|
}) }}
|
||||||
<label class="file-upload-button" for="{{ field.name }}">
|
<label class="file-upload-button" for="{{ field.name }}">
|
||||||
Choose file
|
{{ button_text }}
|
||||||
</label>
|
</label>
|
||||||
<label class="file-upload-filename" for="{{ field.name }}"></label>
|
<label class="file-upload-filename" for="{{ field.name }}"></label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,19 +25,21 @@
|
|||||||
{% macro list_table(items, caption='', empty_message='', field_headings=[], field_headings_visible=True, caption_visible=True) -%}
|
{% macro list_table(items, caption='', empty_message='', field_headings=[], field_headings_visible=True, caption_visible=True) -%}
|
||||||
|
|
||||||
{% set parent_caller = caller %}
|
{% set parent_caller = caller %}
|
||||||
{% if items %}
|
|
||||||
{% call mapping_table(caption, field_headings, field_headings_visible, caption_visible) %}
|
{% call mapping_table(caption, field_headings, field_headings_visible, caption_visible) %}
|
||||||
{% for item in items %}
|
{% for item in items %}
|
||||||
{% call row() %}
|
{% call row() %}
|
||||||
{{ parent_caller(item) }}
|
{{ parent_caller(item) }}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%- endcall %}
|
{% if not items %}
|
||||||
{% else %}
|
{% call row() %}
|
||||||
<p class="table-empty-message">
|
<td class="table-empty-message" colspan="10">
|
||||||
{{ empty_message }}
|
{{ empty_message }}
|
||||||
</p>
|
</td>
|
||||||
{% endif %}
|
{% endcall %}
|
||||||
|
{% endif %}
|
||||||
|
{%- endcall %}
|
||||||
|
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
{% for category, message in messages %}
|
{% for category, message in messages %}
|
||||||
{{ banner(
|
{{ banner(
|
||||||
message,
|
message,
|
||||||
'default' if category == 'default' else 'dangerous',
|
'default' if category == 'default' or 'default_with_tick' else 'dangerous',
|
||||||
delete_button="Yes, delete this template" if 'delete' == category else None
|
delete_button="Yes, delete this template" if 'delete' == category else None,
|
||||||
|
with_tick=True if category == 'default_with_tick' else False
|
||||||
)}}
|
)}}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ GOV.UK Notify | Set up service
|
|||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Users will see your service name:
|
Users will see your service name when they receive messages through GOV.UK
|
||||||
|
Notify:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul class="list-bullet bottom-gutter">
|
<ul class="list-bullet bottom-gutter">
|
||||||
@@ -30,7 +31,7 @@ GOV.UK Notify | Set up service
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<form autocomplete="off" method="post">
|
<form autocomplete="off" method="post">
|
||||||
{{ textbox(form.name) }}
|
{{ textbox(form.name, hint="You can change this later") }}
|
||||||
{{ page_footer('Continue') }}
|
{{ page_footer('Continue') }}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "withnav_template.html" %}
|
{% extends "withnav_template.html" %}
|
||||||
{% from "components/sms-message.html" import sms_message %}
|
{% from "components/sms-message.html" import sms_message %}
|
||||||
{% from "components/table.html" import table, field %}
|
{% from "components/table.html" import list_table, field %}
|
||||||
{% from "components/placeholder.html" import placeholder %}
|
{% from "components/placeholder.html" import placeholder %}
|
||||||
{% from "components/page-footer.html" import page_footer %}
|
{% from "components/page-footer.html" import page_footer %}
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
<h1 class="heading-large">Send text messages</h1>
|
<h1 class="heading-large">Check and confirm</h1>
|
||||||
|
|
||||||
{% if upload_result.rejects %}
|
{% if upload_result.rejects %}
|
||||||
<h3 class="heading-small">The following numbers are invalid</h3>
|
<h3 class="heading-small">The following numbers are invalid</h3>
|
||||||
@@ -21,44 +21,29 @@
|
|||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
<h2 class="heading-medium">Check and confirm</h2>
|
<div class="grid-row">
|
||||||
|
<div class="column-two-thirds">
|
||||||
|
{{ sms_message(
|
||||||
|
message_template|replace_placeholders(upload_result.valid[0])
|
||||||
|
)}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<form method="POST" enctype="multipart/form-data">
|
<form method="POST" enctype="multipart/form-data">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
{{ page_footer(
|
<input type="submit" class="button" value="{{ "Send {} text message{}".format(upload_result.valid|count, '' if upload_result.valid|count == 1 else 's') }}" />
|
||||||
button_text = "Send {} text messages".format(upload_result.valid|count),
|
<a href="{{url_for('.send_sms', service_id=service_id, template_id=template_id)}}" class="page-footer-back-link">Back</a>
|
||||||
back_link = url_for(".send_sms", service_id=service_id, template_id=template_id)
|
|
||||||
)}}
|
|
||||||
|
|
||||||
{% if upload_result.valid | count > 6 %}
|
|
||||||
<h3 class="heading-small">First three message in file</h3>
|
|
||||||
{% for recipient in upload_result.valid[:3] %}
|
|
||||||
{{ sms_message(message_template|replace_placeholders(
|
|
||||||
recipient),
|
|
||||||
'{}'.format(recipient['phone'])
|
|
||||||
)}}
|
|
||||||
{% endfor %}
|
|
||||||
<h3 class="heading-small">Last three messages in file</h3>
|
|
||||||
{% for recipient in upload_result.valid[-3:] %}
|
|
||||||
{{ sms_message(message_template|replace_placeholders(
|
|
||||||
recipient),
|
|
||||||
'{}'.format(recipient['phone'])
|
|
||||||
)}}
|
|
||||||
{% endfor %}
|
|
||||||
{% else %}
|
|
||||||
<h3 class="heading-small">All messages in file</h3>
|
|
||||||
{% for recipient in upload_result.valid %}
|
|
||||||
{{ sms_message(message_template|replace_placeholders(
|
|
||||||
recipient),
|
|
||||||
'{}'.format(recipient['phone'])
|
|
||||||
)}}
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{{ page_footer(
|
|
||||||
button_text = "Send {} text messages".format(upload_result.valid|count),
|
|
||||||
back_link = url_for(".send_sms", service_id=service_id, template_id=template_id)
|
|
||||||
)}}
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
{% call(item) list_table(
|
||||||
|
upload_result.valid,
|
||||||
|
caption=original_file_name,
|
||||||
|
field_headings=['Phone number']
|
||||||
|
) %}
|
||||||
|
{% call field() %}
|
||||||
|
{{ item.phone }}
|
||||||
|
{% endcall %}
|
||||||
|
{% endcall %}
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -8,20 +8,24 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
|
<h1 class="heading-large">Send text messages</h1>
|
||||||
|
|
||||||
<form method="POST" enctype="multipart/form-data">
|
<form method="POST" enctype="multipart/form-data">
|
||||||
|
|
||||||
<h1 class="heading-large">Send text messages</h1>
|
|
||||||
|
|
||||||
{% if templates %}
|
{% if templates %}
|
||||||
<fieldset class='form-group'>
|
<div class="grid-row">
|
||||||
{% for template in templates %}
|
{% for template in templates %}
|
||||||
{{ sms_message(
|
<div class="column-two-thirds">
|
||||||
template.content, name=template.name, input_name='template', input_index=template.id
|
{{ sms_message(template.content, name=template.name) }}
|
||||||
) }}
|
</div>
|
||||||
|
<div class="column-one-third">
|
||||||
|
<div class="sms-message-use-link">
|
||||||
|
<a href="{{ url_for(".send_sms", service_id=service_id, template_id=template.id) }}">Use this template</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</fieldset>
|
</div>
|
||||||
|
|
||||||
{{ page_footer("Continue") }}
|
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ banner(
|
{{ banner(
|
||||||
'<a href="{}">Add a text message template</a> to start sending messages'.format(
|
'<a href="{}">Add a text message template</a> to start sending messages'.format(
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ GOV.UK Notify | API keys and documentation
|
|||||||
|
|
||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
|
<h1 class="heading-large">
|
||||||
|
Developer documentation
|
||||||
|
</h1>
|
||||||
|
|
||||||
<div class="grid-row">
|
<div class="grid-row">
|
||||||
<div class="column-two-thirds">
|
<div class="column-two-thirds">
|
||||||
|
|
||||||
<h1 class="heading-large">
|
|
||||||
Developer documentation
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<h2 class="heading-medium">
|
<h2 class="heading-medium">
|
||||||
How to integrate GOV.UK Notify into your service
|
How to integrate GOV.UK Notify into your service
|
||||||
</h2>
|
</h2>
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
{% from "components/table.html" import list_table, field, right_aligned_field_heading %}
|
{% from "components/table.html" import list_table, field, right_aligned_field_heading %}
|
||||||
{% from "components/big-number.html" import big_number %}
|
{% from "components/big-number.html" import big_number %}
|
||||||
{% from "components/banner.html" import banner %}
|
{% from "components/banner.html" import banner %}
|
||||||
|
{% from "components/sms-message.html" import sms_message %}
|
||||||
|
|
||||||
{% block page_title %}
|
{% block page_title %}
|
||||||
GOV.UK Notify | Notifications activity
|
GOV.UK Notify | Notifications activity
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
@@ -13,55 +14,66 @@ GOV.UK Notify | Notifications activity
|
|||||||
{{ uploaded_file_name }}
|
{{ uploaded_file_name }}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p>
|
<div class="grid-row">
|
||||||
{{ banner(flash_message, with_tick=True) }}
|
<div class="column-two-thirds">
|
||||||
|
{{ sms_message(
|
||||||
|
template['content'],
|
||||||
|
)}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class='heading-small'>
|
||||||
|
Started {{ uploaded_file_time|format_datetime }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul class="grid-row job-totals">
|
<ul class="grid-row job-totals">
|
||||||
<li class="column-one-third">
|
<li class="column-one-quarter">
|
||||||
{{ big_number(
|
{{ big_number(
|
||||||
counts.total,
|
1, 'queued'
|
||||||
'text message' if 1 == counts.total else 'text messages'
|
|
||||||
)}}
|
)}}
|
||||||
</li>
|
</li>
|
||||||
<li class="column-one-third">
|
<li class="column-one-quarter">
|
||||||
|
{{ big_number(
|
||||||
|
0, 'sent'
|
||||||
|
)}}
|
||||||
|
</li>
|
||||||
|
<li class="column-one-quarter">
|
||||||
{{ big_number(
|
{{ big_number(
|
||||||
counts.failed,
|
counts.failed,
|
||||||
'failed delivery' if 1 == counts.failed else 'failed deliveries'
|
'failed'
|
||||||
)}}
|
)}}
|
||||||
</li>
|
</li>
|
||||||
<li class="column-one-third">
|
<li class="column-one-quarter">
|
||||||
{{ big_number(
|
{{ big_number(
|
||||||
cost, 'total cost'
|
cost, 'total cost'
|
||||||
)}}
|
)}}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>
|
|
||||||
Sent with template <a href="{{ url_for('.edit_service_template', service_id=service_id, template_id=template_used) }}">{{ template_used }}</a> on {{ uploaded_file_time | format_datetime}}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{% call(item) list_table(
|
{% call(item) list_table(
|
||||||
messages,
|
[
|
||||||
caption='Messages',
|
{'phone': '+447700 900995', 'template': template['name'], 'status': 'queued'}
|
||||||
|
],
|
||||||
|
caption=uploaded_file_name,
|
||||||
caption_visible=False,
|
caption_visible=False,
|
||||||
|
empty_message="Messages go here",
|
||||||
field_headings=[
|
field_headings=[
|
||||||
'To',
|
'Recipient',
|
||||||
'Message',
|
'Template',
|
||||||
right_aligned_field_heading('Delivery status')
|
right_aligned_field_heading('Status')
|
||||||
]
|
]
|
||||||
) %}
|
) %}
|
||||||
{% call field() %}
|
{% call field() %}
|
||||||
<a href="{{ url_for('.view_notification', service_id=service_id, job_id=456, notification_id=item.id) }}">{{item.phone}}</a>
|
{{item.phone}}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
{% call field() %}
|
{% call field() %}
|
||||||
<a href="{{ url_for('.view_notification', service_id=service_id, job_id=456, notification_id=item.id) }}">{{item.message[:50]}}…</a>
|
{{item.template}}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
{% call field(
|
{% call field(
|
||||||
align='right',
|
align='right',
|
||||||
status='error' if item.status == 'Failed' else 'default'
|
status='error' if item.status == 'Failed' else 'default'
|
||||||
) %}
|
) %}
|
||||||
{{ item.status }} {{ item.time }}
|
{{ item.status }}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
|
|
||||||
|
|||||||
@@ -11,13 +11,16 @@ GOV.UK Notify | Manage templates
|
|||||||
|
|
||||||
<h1 class="heading-large">Templates</h1>
|
<h1 class="heading-large">Templates</h1>
|
||||||
|
|
||||||
{{ banner(
|
|
||||||
'<a href="{}">Try sending a text message</a>'.format(
|
{% if not has_jobs %}
|
||||||
url_for(".choose_sms_template", service_id=service_id)
|
{{ banner(
|
||||||
)|safe,
|
'<a href="{}">Send yourself a text message</a>'.format(
|
||||||
subhead='Next step',
|
url_for(".choose_sms_template", service_id=service_id)
|
||||||
type="tip"
|
)|safe,
|
||||||
)}}
|
subhead='Next step',
|
||||||
|
type="tip"
|
||||||
|
)}}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<div class="grid-row">
|
<div class="grid-row">
|
||||||
<div class="column-two-thirds">
|
<div class="column-two-thirds">
|
||||||
|
|||||||
@@ -8,37 +8,28 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
|
<h1 class="heading-large">Send text messages</h1>
|
||||||
|
|
||||||
<form method="POST" enctype="multipart/form-data">
|
<form method="POST" enctype="multipart/form-data">
|
||||||
|
|
||||||
<h1 class="heading-large">Send text messages</h1>
|
<div class="grid-row">
|
||||||
|
<div class="column-two-thirds">
|
||||||
|
{{ sms_message(template.content) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{ banner(
|
{{file_upload(form.file, button_text='Choose a CSV file')}}
|
||||||
'You can only send notifications to yourself',
|
|
||||||
subhead='Trial mode',
|
|
||||||
type='info'
|
|
||||||
) }}
|
|
||||||
|
|
||||||
{{ sms_message(
|
|
||||||
template.content, name='Preview'
|
|
||||||
) }}
|
|
||||||
|
|
||||||
{{ banner(
|
{{ banner(
|
||||||
'You can only send messages to yourself until you <a href="{}">request to go live</a>'.format(
|
'You can only send messages to yourself until you <a href="{}">request to go live</a>'.format(
|
||||||
url_for('.service_request_to_go_live', service_id=service_id)
|
url_for('.service_request_to_go_live', service_id=service_id)
|
||||||
)|safe,
|
)|safe,
|
||||||
type='info'
|
type='important'
|
||||||
) }}
|
) }}
|
||||||
|
|
||||||
{{file_upload(form.file)}}
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="#">Download an example CSV</a> to test with.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{{ page_footer(
|
{{ page_footer(
|
||||||
"Continue",
|
"Continue to preview"
|
||||||
back_link=url_for(".choose_sms_template", service_id=service_id),
|
|
||||||
back_link_text="Back to templates"
|
|
||||||
) }}
|
) }}
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "withnav_template.html" %}
|
{% extends "withnav_template.html" %}
|
||||||
{% from "components/table.html" import list_table, field %}
|
{% from "components/table.html" import list_table, field, right_aligned_field_heading %}
|
||||||
{% from "components/big-number.html" import big_number %}
|
{% from "components/big-number.html" import big_number %}
|
||||||
|
|
||||||
{% block page_title %}
|
{% block page_title %}
|
||||||
@@ -23,41 +23,38 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{% if not template_count %}
|
{% if not jobs %}
|
||||||
{{ banner(
|
{{ banner(
|
||||||
'<a href="{}">Add a text message template</a>'.format(
|
"""
|
||||||
url_for(".add_service_template", service_id=service_id)
|
<ol>
|
||||||
|
<li>
|
||||||
|
<a href='{}'>Add a template</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href='{}'>Send yourself a text message</a>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
""".format(
|
||||||
|
url_for(".add_service_template", service_id=service_id),
|
||||||
|
url_for(".choose_sms_template", service_id=service_id)
|
||||||
)|safe,
|
)|safe,
|
||||||
subhead='Get started',
|
subhead='Get started',
|
||||||
type="tip"
|
type="tip"
|
||||||
)}}
|
)}}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ banner(
|
|
||||||
'<a href="{}">Try sending a text message</a>'.format(
|
|
||||||
url_for(".choose_sms_template", service_id=service_id)
|
|
||||||
)|safe,
|
|
||||||
subhead='Next step',
|
|
||||||
type="tip"
|
|
||||||
)}}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if [] %}
|
|
||||||
{% call(item) list_table(
|
{% call(item) list_table(
|
||||||
[],
|
jobs,
|
||||||
caption="Recent text messages",
|
caption="Recent text messages",
|
||||||
empty_message='You haven’t sent any text messages yet',
|
empty_message='You haven’t sent any text messages yet',
|
||||||
field_headings=['Job', 'File', 'Time', 'Status']
|
field_headings=['Job', 'Created', right_aligned_field_heading('Status')]
|
||||||
) %}
|
) %}
|
||||||
{% call field() %}
|
{% call field() %}
|
||||||
<a href="{{ url_for('.view_job', service_id=service_id, job_id=456) }}">{{ item.file }}</a>
|
<a href="{{ url_for('.view_job', service_id=service_id, job_id=item.id) }}">{{ item.original_file_name }}</a>
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
{% call field() %}
|
{% call field() %}
|
||||||
<a href="{{ url_for('.view_job', service_id=service_id, job_id=456) }}">{{ item.job }}</a>
|
{{ item.created_at|format_datetime }}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
{% call field() %}
|
{% call field(align='right') %}
|
||||||
{{ item.time }}
|
|
||||||
{% endcall %}
|
|
||||||
{% call field() %}
|
|
||||||
{{ item.status }}
|
{{ item.status }}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<div class="column-one-third">
|
<div class="column-one-third">
|
||||||
{% include "main_nav.html" %}
|
{% include "main_nav.html" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="column-two-thirds">
|
<div class="column-two-thirds column-main">
|
||||||
{% include 'flash_messages.html' %}
|
{% include 'flash_messages.html' %}
|
||||||
{% block maincolumn_content %}{% endblock %}
|
{% block maincolumn_content %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ def test_should_show_recent_jobs_on_dashboard(app_,
|
|||||||
mock_get_service_templates,
|
mock_get_service_templates,
|
||||||
mock_get_user,
|
mock_get_user,
|
||||||
mock_get_user_by_email,
|
mock_get_user_by_email,
|
||||||
mock_login):
|
mock_login,
|
||||||
|
mock_get_jobs):
|
||||||
|
|
||||||
with app_.test_request_context():
|
with app_.test_request_context():
|
||||||
with app_.test_client() as client:
|
with app_.test_client() as client:
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ def test_should_show_page_for_one_job(app_,
|
|||||||
mock_login,
|
mock_login,
|
||||||
mock_get_user,
|
mock_get_user,
|
||||||
mock_get_user_by_email,
|
mock_get_user_by_email,
|
||||||
|
mock_get_service_template,
|
||||||
job_data,
|
job_data,
|
||||||
mock_get_job):
|
mock_get_job):
|
||||||
service_id = job_data['service']
|
service_id = job_data['service']
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ def test_sign_out_user(app_,
|
|||||||
mock_get_user,
|
mock_get_user,
|
||||||
mock_get_user_by_email,
|
mock_get_user_by_email,
|
||||||
mock_get_service_templates,
|
mock_get_service_templates,
|
||||||
mock_login):
|
mock_login,
|
||||||
|
mock_get_jobs):
|
||||||
with app_.test_request_context():
|
with app_.test_request_context():
|
||||||
email = 'valid@example.gov.uk'
|
email = 'valid@example.gov.uk'
|
||||||
password = 'val1dPassw0rd!'
|
password = 'val1dPassw0rd!'
|
||||||
|
|||||||
@@ -23,24 +23,6 @@ def test_choose_sms_template(app_,
|
|||||||
assert 'template two content' in content
|
assert 'template two content' in content
|
||||||
|
|
||||||
|
|
||||||
def test_choose_sms_template_redirects(app_,
|
|
||||||
api_user_active,
|
|
||||||
mock_get_user,
|
|
||||||
mock_get_service_templates,
|
|
||||||
mock_check_verify_code,
|
|
||||||
mock_get_service_template):
|
|
||||||
with app_.test_request_context():
|
|
||||||
with app_.test_client() as client:
|
|
||||||
client.login(api_user_active)
|
|
||||||
response = client.post(
|
|
||||||
url_for('main.choose_sms_template', service_id=12345),
|
|
||||||
data={'template': '54321'}
|
|
||||||
)
|
|
||||||
|
|
||||||
assert response.status_code == 302
|
|
||||||
assert response.location == url_for('main.send_sms', service_id=12345, template_id=54321, _external=True)
|
|
||||||
|
|
||||||
|
|
||||||
def test_upload_empty_csvfile_returns_to_upload_page(app_,
|
def test_upload_empty_csvfile_returns_to_upload_page(app_,
|
||||||
api_user_active,
|
api_user_active,
|
||||||
mock_get_user,
|
mock_get_user,
|
||||||
@@ -87,50 +69,13 @@ def test_upload_csvfile_with_invalid_phone_shows_check_page_with_errors(app_,
|
|||||||
|
|
||||||
|
|
||||||
@moto.mock_s3
|
@moto.mock_s3
|
||||||
def test_upload_csvfile_with_valid_phone_shows_first3_and_last3_numbers(app_,
|
def test_upload_csvfile_with_valid_phone_shows_all_numbers(app_,
|
||||||
mocker,
|
mocker,
|
||||||
api_user_active,
|
api_user_active,
|
||||||
mock_get_user,
|
mock_get_user,
|
||||||
mock_get_user_by_email,
|
mock_get_user_by_email,
|
||||||
mock_login,
|
mock_login,
|
||||||
mock_get_service_template):
|
mock_get_service_template):
|
||||||
contents = 'phone\n+44 7700 900981\n+44 7700 900982\n+44 7700 900983\n+44 7700 900984\n+44 7700 900985\n+44 7700 900986\n+44 7700 900987\n+44 7700 900988\n+44 7700 900989' # noqa
|
|
||||||
|
|
||||||
file_data = (BytesIO(contents.encode('utf-8')), 'valid.csv')
|
|
||||||
|
|
||||||
with app_.test_request_context():
|
|
||||||
with app_.test_client() as client:
|
|
||||||
client.login(api_user_active)
|
|
||||||
upload_data = {'file': file_data}
|
|
||||||
response = client.post(url_for('main.send_sms', service_id=12345, template_id=54321),
|
|
||||||
data=upload_data,
|
|
||||||
follow_redirects=True)
|
|
||||||
|
|
||||||
content = response.get_data(as_text=True)
|
|
||||||
|
|
||||||
assert response.status_code == 200
|
|
||||||
assert 'Check and confirm' in content
|
|
||||||
assert 'First three message in file' in content
|
|
||||||
assert 'Last three messages in file' in content
|
|
||||||
assert '+44 7700 900981' in content
|
|
||||||
assert '+44 7700 900982' in content
|
|
||||||
assert '+44 7700 900983' in content
|
|
||||||
assert '+44 7700 900984' not in content
|
|
||||||
assert '+44 7700 900985' not in content
|
|
||||||
assert '+44 7700 900986' not in content
|
|
||||||
assert '+44 7700 900987' in content
|
|
||||||
assert '+44 7700 900988' in content
|
|
||||||
assert '+44 7700 900989' in content
|
|
||||||
|
|
||||||
|
|
||||||
@moto.mock_s3
|
|
||||||
def test_upload_csvfile_with_valid_phone_shows_all_if_6_or_less_numbers(app_,
|
|
||||||
mocker,
|
|
||||||
api_user_active,
|
|
||||||
mock_get_user,
|
|
||||||
mock_get_user_by_email,
|
|
||||||
mock_login,
|
|
||||||
mock_get_service_template):
|
|
||||||
|
|
||||||
contents = 'phone\n+44 7700 900981\n+44 7700 900982\n+44 7700 900983\n+44 7700 900984\n+44 7700 900985\n+44 7700 900986' # noqa
|
contents = 'phone\n+44 7700 900981\n+44 7700 900982\n+44 7700 900983\n+44 7700 900984\n+44 7700 900985\n+44 7700 900986' # noqa
|
||||||
|
|
||||||
@@ -147,8 +92,6 @@ def test_upload_csvfile_with_valid_phone_shows_all_if_6_or_less_numbers(app_,
|
|||||||
content = response.get_data(as_text=True)
|
content = response.get_data(as_text=True)
|
||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert 'Check and confirm' in content
|
|
||||||
assert 'All messages in file' in content
|
|
||||||
assert '+44 7700 900981' in content
|
assert '+44 7700 900981' in content
|
||||||
assert '+44 7700 900982' in content
|
assert '+44 7700 900982' in content
|
||||||
assert '+44 7700 900983' in content
|
assert '+44 7700 900983' in content
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ def test_should_return_list_of_all_templates(app_,
|
|||||||
mock_get_service_templates,
|
mock_get_service_templates,
|
||||||
mock_get_user,
|
mock_get_user,
|
||||||
mock_get_user_by_email,
|
mock_get_user_by_email,
|
||||||
mock_login):
|
mock_login,
|
||||||
|
mock_get_jobs):
|
||||||
with app_.test_request_context():
|
with app_.test_request_context():
|
||||||
with app_.test_client() as client:
|
with app_.test_client() as client:
|
||||||
client.login(api_user_active)
|
client.login(api_user_active)
|
||||||
|
|||||||
Reference in New Issue
Block a user