Merge pull request #613 from alphagov/no-tour-final

Make the tour interactive
This commit is contained in:
Chris Hill-Scott
2016-05-25 17:26:48 +01:00
33 changed files with 146 additions and 234 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 251 KiB

View File

@@ -10,6 +10,10 @@
@include grid-column(1/6);
}
.column-five-sixths {
@include grid-column(5/6);
}
.column-one-eighth {
@include grid-column(1/8);
}

View File

@@ -84,7 +84,7 @@
}
&-action {
display: block;
text-align: right;
float: right;
@@ -115,14 +115,19 @@
background: $govuk-blue;
color: $white;
margin-top: $gutter;
padding: $gutter * 2;
margin-bottom: $gutter * -3;
padding: $gutter;
height: 475px;
overflow: hidden;
box-shadow: inset 0 -1em 1.6em 0 rgba(0, 0, 0, 0.05);
.heading-large {
margin: 0 0 $gutter 0;
.heading-medium {
@include core-24;
}
p {
margin-top: 0;
margin-bottom: $gutter;
&:last-child {
@@ -137,13 +142,10 @@
a {
@include bold-24;
display: inline-block;
background-image: file-url('tour-next.png');
background-size: auto 24px;
padding: 0 23px 0 0;
background-position: right 3px;
background-repeat: no-repeat;
@include bold-19;
display: block;
padding: 0 ;
margin: 0 0 $gutter 0;
&:link,
&:visited {
@@ -164,14 +166,17 @@
}
img,
source {
max-width: 100%;
display: block;
th {
padding: inherit 5px;
background: $grey-3;
border-left: 5px solid $grey-3;
border-right: 5px solid $grey-3;
}
&-image-flush-bottom {
margin: 40px 0 -60px 0;
tr:last-child {
td {
border: none;
}
}
}

View File

@@ -53,6 +53,11 @@
&-alternate-link {
display: inline-block;
line-height: 35px;
a {
@include bold-19;
}
}
}

View File

@@ -14,6 +14,7 @@
p {
margin: 0;
line-height: 1.6;
}
p + p {

View File

@@ -16,13 +16,14 @@
&-background,
&-foreground,
&-mask {
@include core-19;
font-size: 19px;
display: block;
box-sizing: border-box;
position: relative;
margin: 0;
padding: 4px;
overflow: hidden;
line-height: 1.6;
}
&-background,

View File

@@ -25,7 +25,6 @@ from app.main.views import (
manage_users,
invites,
all_services,
tour,
feedback,
providers,
platform_admin

View File

@@ -44,11 +44,29 @@ def add_service():
email_from=email_from)
session['service_id'] = service_id
services = service_api_client.get_services({'user_id': session['user_id']}).get('data', [])
if (len(services) > 1):
if (len(service_api_client.get_services({'user_id': session['user_id']}).get('data', [])) > 1):
return redirect(url_for('main.service_dashboard', service_id=service_id))
else:
return redirect(url_for('main.tour', page=1))
example_sms_template = service_api_client.create_service_template(
'Example text message template',
'sms',
'Hey ((name)), Im trying out Notify. Today is ((day of week)) and my favourite colour is ((colour)).',
service_id
)
example_email_template = service_api_client.create_service_template(
'Example email template',
'email',
'Hey ((name)),\n\nIm trying out Notify. Today is ((day of week)) and my favourite colour is ((colour)).',
service_id,
'Trying out Notify'
)
return redirect(url_for(
'main.send_test',
service_id=service_id,
template_id=example_sms_template['data']['id'],
help=1
))
else:
return render_template(
'views/add-service.html',

View File

@@ -45,7 +45,6 @@ def service_dashboard(service_id):
if session.get('invited_user'):
session.pop('invited_user', None)
session['service_id'] = service_id
return redirect(url_for("main.tour", page=1))
return render_template(
'views/dashboard/dashboard.html',

View File

@@ -97,6 +97,10 @@ def view_job(service_id, job_id):
uploaded_at=job['created_at'],
finished_at=job['updated_at'] if finished else None,
uploaded_file_name=job['original_file_name'],
first_email_template=[
template for template in service_api_client.get_service_templates(service_id)['data']
if template['template_type'] == 'email'
][0] if request.args.get('help') else None,
template=Template(
template,
prefix=current_service['name']

View File

@@ -180,7 +180,8 @@ def send_test(service_id, template_id):
upload_id=upload_id,
service_id=service_id,
template_type=template.template_type,
from_test=True
from_test=True,
help=2 if request.args.get('help') else 0
))
return render_template(
@@ -246,7 +247,9 @@ def check_messages(service_id, template_type, upload_id):
)
if request.args.get('from_test') and len(template.placeholders):
back_link = url_for('.send_test', service_id=service_id, template_id=template.id)
back_link = url_for(
'.send_test', service_id=service_id, template_id=template.id, help=1 if request.args.get('help') else 0
)
else:
back_link = url_for('.send_messages', service_id=service_id, template_id=template.id)
@@ -312,5 +315,5 @@ def start_job(service_id, upload_id):
)
return redirect(
url_for('main.view_job', job_id=upload_id, service_id=service_id)
url_for('main.view_job', job_id=upload_id, service_id=service_id, help=request.form.get('help'))
)

View File

@@ -1,21 +0,0 @@
from flask import render_template
from app.main import main
headings = [
'Trial mode',
'Start with templates',
'Add recipients',
'Send your messages',
]
@main.route("/tour/<int:page>")
def tour(page):
return render_template(
'views/tour/{}.html'.format(page),
current_page=page,
next_page=(page + 1),
heading=headings[page - 1]
)

View File

@@ -90,7 +90,6 @@
<div class="column-one-third">
<h2>Help</h2>
<ul>
<li><a href="{{ url_for('main.tour', page=1) }}">Tour</a></li>
<li><a href="{{ url_for("main.trial_mode") }}">Trial mode</a></li>
<li><a href="{{ url_for("main.pricing") }}">Pricing</a></li>
<li><a href="{{ url_for("main.delivery_and_failure") }}">Delivery and failure</a></li>

View File

@@ -1,3 +1,51 @@
{% from "components/banner.html" import banner_wrapper %}
{% if request.args['help'] %}
{% call banner_wrapper(type='tour') %}
<p class="heading-medium">Get started</p>
<div class="grid-row bottom-gutter" {% if request.args['help'] != '1' %}style="opacity: 0.6"{% endif %}>
<div class="column-one-sixth">
<p class="heading-large" style="float: left;">1.</p>
</div>
<div class="column-five-sixths">
<p>
Send yourself this example message
</p>
</div>
</div>
<div class="grid-row bottom-gutter" {% if request.args['help'] != '2' %}style="opacity: 0.6"{% endif %}>
<div class="column-one-sixth">
<p class="heading-large">2.</p>
</div>
<div class="column-five-sixths">
<p>
The template pulls in the data you provide
</p>
</div>
</div>
<div class="grid-row bottom-gutter" {% if request.args['help'] != '3' %}style="opacity: 0.6"{% endif %}>
<div class="column-one-sixth">
<p class="heading-large">3.</p>
</div>
<div class="column-five-sixths">
<p>
Now try it with your own message
</p>
{% if request.args['help'] == '3' %}
{% if first_email_template %}
<a href='{{ url_for(".edit_service_template", service_id=current_service.id, template_id=first_email_template.id) }}'>
Write an email
</a>
{% endif %}
<a href='{{ url_for(".edit_service_template", service_id=current_service.id, template_id=template.id) }}'>
Write a text message
</a>
{% endif %}
</div>
</div>
{% endcall %}
{% else %}
<nav class="navigation">
<h2 class="navigation-service-name">
<a href="{{ url_for('.service_dashboard', service_id=current_service.id) }}">{{ current_service.name }}</a>
@@ -18,3 +66,4 @@
{% endif %}
</ul>
</nav>
{% endif %}

View File

@@ -17,14 +17,10 @@
caption_visible=False,
empty_message="No messages to show yet",
field_headings=[
'1',
'Recipient',
right_aligned_field_heading('Status')
]
) %}
{% call field() %}
{{ item.job_row_number + 2 }}
{% endcall %}
{% call field() %}
{{ item.to }}
{% endcall %}

View File

@@ -6,15 +6,7 @@
aria-live="polite"
{% endif %}
>
{% if finished_at %}
<p class='heading-small'>
Finished {{ finished_at|format_datetime }}
</p>
{% else %}
<p class='heading-small'>
Started {{ uploaded_at|format_datetime }}
</p>
{% endif %}
Uploaded by {{ created_by }}
<p class='heading-small'>
Sent by {{ created_by }} on {{ uploaded_at|format_datetime_short }}
</p>
</div>

View File

@@ -122,6 +122,7 @@
{% else %}
<form method="post" enctype="multipart/form-data" action="{{url_for('main.start_job', service_id=current_service.id, upload_id=upload_id)}}" class='page-footer'>
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input type="hidden" name="help" value="{{ '3' if request.args['help'] else 0 }}" />
<input type="submit" class="button" value="{{ send_button_text }}" />
<a href="{{ back_link }}" class="page-footer-back-link">Back</a>
</form>

View File

@@ -27,9 +27,9 @@
) }}
</div>
<div class="column-one-third">
<label for='template_content' class='placeholder-hint banner-mode' data-module='placeholder-hint' data-textboxes-selector='#template_content,#subject' data-target-textbox-selector="#template_content">
<label for='template_content' class='placeholder-hint banner-mode' data-textboxes-selector='#template_content,#subject' data-target-textbox-selector="#template_content">
<div class="" id="placeholder-hint" aria-live="polite">
<p>Add fields to the subject or message content using ((double brackets))</p>
<p>Anything in ((double brackets)) gets replaced when you send this message</p>
</div>
</label>
</div>

View File

@@ -26,9 +26,9 @@
) }}
</div>
<div class="column-one-third">
<label for='template_content' class='placeholder-hint banner-mode' data-module='placeholder-hint' data-textboxes-selector='#template_content' data-target-textbox-selector="#template_content">
<label for='template_content' class='placeholder-hint banner-mode' data-textboxes-selector='#template_content' data-target-textbox-selector="#template_content">
<div class="" id="placeholder-hint" aria-live="polite">
<p>Add fields using ((double brackets))</p>
<p>Anything in ((double brackets)) gets replaced when you send this message</p>
</div>
</label>
</div>

View File

@@ -11,8 +11,11 @@
{% block maincolumn_content %}
<h1 class="heading-large">Send a test</h1>
{% if request.args['help'] %}
<h1 class="heading-large">Example text message</h1>
{% else %}
<h1 class="heading-large">Send a test</h1>
{% endif %}
{% if 'sms' == template.template_type %}
<div class="grid-row">
@@ -36,7 +39,7 @@
<form method="post">
{% call(item, row_number) list_table(
example,
caption="Fill in your {}".format('field' if template.placeholders|length == 1 else 'fields'),
caption="Fill in the {}".format('field' if template.placeholders|length == 1 else 'fields'),
field_headings=[
'<span class="placeholder">{}</span>'.format(recipient_column)|safe
] + template.placeholders_as_markup|list
@@ -53,7 +56,9 @@
{% endfor %}
{% endcall %}
{{ page_footer("Check and confirm", back_link=url_for('.send_messages', service_id=current_service.id, template_id=template.id)) }}
{{ page_footer("Check and confirm", back_link=(
url_for('.send_messages', service_id=current_service.id, template_id=template.id)) if not request.args['help'] else None
) }}
</form>
{% endblock %}

View File

@@ -1,25 +0,0 @@
{% extends "withoutnav_template.html" %}
{% from "components/textbox.html" import textbox %}
{% from "components/page-footer.html" import page_footer %}
{% from "components/banner.html" import banner_wrapper %}
{% block page_title %}
{{heading}} GOV.UK Notify
{% endblock %}
{% block maincolumn_content %}
{% call banner_wrapper(type='tour') %}
<h2 class="heading-large">{{ heading }}</h2>
<p>
To start off with, you can only send messages to yourself.
</p>
<p>
We can remove these restrictions when youre ready.
</p>
<a href='{{ url_for('.tour', page=next_page) }}'>
Next
</a>
{% endcall %}
{% endblock %}

View File

@@ -1,37 +0,0 @@
{% extends "withoutnav_template.html" %}
{% from "components/textbox.html" import textbox %}
{% from "components/page-footer.html" import page_footer %}
{% from "components/banner.html" import banner_wrapper %}
{% block page_title %}
{{heading}} GOV.UK Notify
{% endblock %}
{% block maincolumn_content %}
{% call banner_wrapper(type='tour') %}
<h2 class="heading-large">{{ heading }}</h2>
<p>
Set up a template like this:
</p>
<p>
<picture>
<source
type="image/svg+xml"
srcset="/static/images/tour/{{ current_page }}.svg"
alt="A template for a text message with placeholders for the recipients name, document and date"
width="554" height="97"
>
<img
src="/static/images/tour/{{ current_page }}.png"
width="554" height="97"
alt="A screenshot of a spreadsheet containing data about three people"
>
</picture>
</p>
<a href='{{ url_for('.tour', page=next_page) }}'>
Next
</a>
{% endcall %}
{% endblock %}

View File

@@ -1,40 +0,0 @@
{% extends "withoutnav_template.html" %}
{% from "components/textbox.html" import textbox %}
{% from "components/page-footer.html" import page_footer %}
{% from "components/banner.html" import banner_wrapper %}
{% block page_title %}
{{heading}} GOV.UK Notify
{% endblock %}
{% block maincolumn_content %}
{% call banner_wrapper(type='tour') %}
<h2 class="heading-large">{{ heading }}</h2>
<p>
Add recipients by uploading a .csv spreadsheet:
</p>
<p>
<picture>
<source
type="image/svg+xml"
srcset="/static/images/tour/{{ current_page }}.svg"
alt="A screenshot of a spreadsheet containing data about three people"
width="554" height="118"
>
<img
src="/static/images/tour/{{ current_page }}.png"
width="554" height="118"
alt="A screenshot of a spreadsheet containing data about three people"
>
</picture>
</p>
<p>
Developers, you can add data automatically using an API
</p>
<a href='{{ url_for('.tour', page=next_page) }}'>
Next
</a>
{% endcall %}
{% endblock %}

View File

@@ -1,36 +0,0 @@
{% extends "withoutnav_template.html" %}
{% from "components/textbox.html" import textbox %}
{% from "components/page-footer.html" import page_footer %}
{% from "components/banner.html" import banner_wrapper %}
{% block page_title %}
{{ heading }} GOV.UK Notify
{% endblock %}
{% block maincolumn_content %}
{% call banner_wrapper(type='tour') %}
<h2 class="heading-large">{{ heading }}</h2>
<p>
Notify merges your data with the template and sends the messages
</p>
<a href="{{ url_for('.show_all_services_or_dashboard') }}">
Next
</a>
<picture class="banner-tour-image-flush-bottom">
<source
type="image/svg+xml"
srcset="/static/images/tour/{{ current_page }}.svg"
alt="Three mobiles phones, each showing a text message personalised with data about the recipient"
width="840" height="290"
>
<img
src="/static/images/tour/{{ current_page }}.png"
class="banner-tour-image-flush-bottom"
width="840" height="290"
alt="Three mobiles phones, each showing a text message personalised with data about the recipient"
>
</picture>
{% endcall %}
{% endblock %}

View File

@@ -1,5 +1,5 @@
from flask import url_for, session
from unittest.mock import ANY
import app
@@ -17,6 +17,7 @@ def test_get_should_render_add_service_template(app_,
def test_should_add_service_and_redirect_to_tour_when_no_services(app_,
mocker,
mock_create_service,
mock_create_service_template,
mock_get_services_with_no_services,
api_user_active):
with app_.test_request_context():
@@ -34,14 +35,22 @@ def test_should_add_service_and_redirect_to_tour_when_no_services(app_,
user_id=api_user_active.id,
email_from='testing.the.post'
)
assert len(mock_create_service_template.call_args_list) == 2
assert session['service_id'] == 101
assert response.status_code == 302
assert response.location == url_for('main.tour', page=1, _external=True)
assert response.location == url_for(
'main.send_test',
service_id=101,
template_id="Example text message template",
help=1,
_external=True
)
def test_should_add_service_and_redirect_to_dashboard_when_existing_service(app_,
mocker,
mock_create_service,
mock_create_service_template,
mock_get_services,
api_user_active):
with app_.test_request_context():
@@ -59,6 +68,7 @@ def test_should_add_service_and_redirect_to_dashboard_when_existing_service(app_
user_id=api_user_active.id,
email_from='testing.the.post'
)
assert len(mock_create_service_template.call_args_list) == 0
assert session['service_id'] == 101
assert response.status_code == 302
assert response.location == url_for('main.service_dashboard', service_id=101, _external=True)

View File

@@ -70,7 +70,7 @@ def test_should_show_updates_for_one_job_as_json(
assert 'queued' in content['counts']
assert 'Recipient' in content['notifications']
assert 'Status' in content['notifications']
assert 'Started' in content['status']
assert 'Sent by Test User' in content['status']
assert job_json['status'] in content['status']

View File

@@ -1,17 +0,0 @@
import pytest
from flask import url_for
@pytest.mark.parametrize("page", range(1, 5))
def test_should_render_tour_pages(
app_,
api_user_active,
mocker,
mock_get_service,
page
):
with app_.test_request_context():
with app_.test_client() as client:
response = client.get(url_for('main.tour', page=page))
assert response.status_code == 200
assert 'Next' in response.get_data(as_text=True)