Merge pull request #3547 from alphagov/broadcast-tour

Add a tour for users new to broadcast services
This commit is contained in:
Chris Hill-Scott
2020-08-03 14:21:03 +01:00
committed by GitHub
16 changed files with 3400 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

File diff suppressed because one or more lines are too long

View File

@@ -78,6 +78,11 @@
box-shadow: inset 0 -1em 1.6em 0 rgba(0, 0, 0, 0.05);
border: 0;
&-no-fixed-height {
height: auto;
min-height: 425px;
}
.heading-medium {
@include core-24;
}
@@ -98,6 +103,18 @@
}
ul {
@include core-24;
color: $white;
margin-bottom: govuk-spacing(5);
}
li {
margin-bottom: govuk-spacing(3);
list-style-type: disc;
margin-left: govuk-spacing(6);
}
a {
font-weight: bold;
@@ -123,6 +140,10 @@
}
}
img {
width: 100%;
height: auto;
}
.greyed-out-step {
opacity: 0.6;

View File

@@ -19,6 +19,17 @@ from app.models.broadcast_message import BroadcastMessage, BroadcastMessages
from app.utils import service_has_permission, user_has_permissions
@main.route('/services/<uuid:service_id>/broadcast-tour/<int:step_index>')
@user_has_permissions()
@service_has_permission('broadcast')
def broadcast_tour(service_id, step_index):
if step_index not in (1, 2, 3):
abort(404)
return render_template(
f'views/broadcast/tour/{step_index}.html'
)
@main.route('/services/<uuid:service_id>/broadcast-dashboard')
@user_has_permissions()
@service_has_permission('broadcast')

View File

@@ -40,6 +40,9 @@ def accept_invite(token):
if invited_user.status == 'accepted':
session.pop('invited_user', None)
service = Service.from_id(invited_user.service)
if service.has_permission('broadcast'):
return redirect(url_for('main.broadcast_tour', service_id=service.id, step_index=1))
return redirect(url_for('main.service_dashboard', service_id=invited_user.service))
session['invited_user'] = invited_user.serialize()
@@ -66,6 +69,8 @@ def accept_invite(token):
permissions=invited_user.permissions,
folder_permissions=invited_user.folder_permissions,
)
if service.has_permission('broadcast'):
return redirect(url_for('main.broadcast_tour', service_id=service.id, step_index=1))
return redirect(url_for('main.service_dashboard', service_id=service.id))
else:
return redirect(url_for('main.register_from_invite'))

View File

@@ -15,6 +15,7 @@ from notifications_utils.url_safe_token import check_token
from app import user_api_client
from app.main import main
from app.main.forms import TwoFactorForm
from app.models.service import Service
from app.models.user import InvitedUser, User
from app.utils import redirect_to_sign_in
@@ -77,6 +78,9 @@ def activate_user(user_id):
invited_user = session.get('invited_user')
if invited_user:
service_id = _add_invited_user_to_service(invited_user)
service = Service.from_id(service_id)
if service.has_permission('broadcast'):
return redirect(url_for('main.broadcast_tour', service_id=service.id, step_index=1))
return redirect(url_for('main.service_dashboard', service_id=service_id))
invited_org_user = session.get('invited_org_user')

View File

@@ -352,6 +352,7 @@ class HeaderNavigation(Navigation):
'old_guest_list',
'who_can_use_notify',
'who_its_for',
'broadcast_tour',
'broadcast_dashboard',
'broadcast_dashboard_updates',
'broadcast',
@@ -375,6 +376,7 @@ class MainNavigation(Navigation):
mapping = {
'dashboard': {
'broadcast_tour',
'broadcast_dashboard',
'broadcast_dashboard_updates',
'conversation',
@@ -702,6 +704,7 @@ class CaseworkNavigation(Navigation):
mapping = {
'dashboard': {
'broadcast_tour',
'broadcast_dashboard',
'broadcast_dashboard_updates',
},
@@ -1330,6 +1333,7 @@ class OrgNavigation(Navigation):
'old_guest_list',
'who_can_use_notify',
'who_its_for',
'broadcast_tour',
'broadcast_dashboard',
'broadcast_dashboard_updates',
'broadcast',

View File

@@ -10,6 +10,14 @@
<h1 class="govuk-visually-hidden">Dashboard</h1>
{% if current_user.has_permissions('manage_templates') and not current_service.all_templates %}
<nav class="govuk-!-margin-top-2 govuk-!-margin-bottom-6">
<a class="govuk-link govuk-link--no-visited-state pill-separate-item govuk-!-padding-top-4 govuk-!-padding-bottom-4 govuk-!-font-weight-bold" href="{{ url_for('.choose_template', service_id=current_service.id) }}">
Start by creating a template
</a>
</nav>
{% endif %}
<h2 class="heading-medium govuk-!-margin-bottom-2">Live broadcasts</h2>
{{ ajax_block(

View File

@@ -0,0 +1,41 @@
{% from "components/banner.html" import banner_wrapper %}
{% extends "admin_template.html" %}
{% block per_page_title %}
Step 1
{% endblock %}
{% set mainClasses = "govuk-!-padding-top-0 govuk-!-padding-bottom-0" %}
{% block content %}
<div class="banner-tour banner-tour-no-fixed-height govuk-!-margin-top-0">
<div class="govuk-grid-row">
<div class="govuk-grid-column-one-half">
<h1 class="heading-medium">
Youve been invited to use GOV.UK Notify to broadcast alerts
</h1>
<ul>
<li>
Broadcasting is a new technology for alerting members of the
public
</li>
<li>
It should be used when theres an imminent risk to life
</li>
</ul>
<p class="govuk-body heading-medium">
<a class="govuk-link govuk-link--no-visited-state" href='{{ url_for(".broadcast_tour", service_id=current_service.id, step_index=2) }}'>
Find out how it works
</a>
</p>
</div>
<div class="govuk-grid-column-one-half">
<img src="{{ asset_url('images/broadcast-tour/1.png') }}" alt="">
<link rel="preload" href="{{ asset_url('images/broadcast-tour/2.png') }}" as="image">
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,44 @@
{% from "components/banner.html" import banner_wrapper %}
{% extends "admin_template.html" %}
{% block per_page_title %}
Step 2
{% endblock %}
{% set mainClasses = "govuk-!-padding-top-0 govuk-!-padding-bottom-0" %}
{% block content %}
<div class="banner-tour banner-tour-no-fixed-height govuk-!-margin-top-0">
<div class="govuk-grid-row">
<div class="govuk-grid-column-one-half">
<h1 class="heading-medium">
A broadcast will alert every phone in an area
</h1>
<ul>
<li>
The alert will appear even if the phones screen is locked
</li>
<li>
The phone will play an alarm sound even if its set to silent
</li>
<li>
Any phone that enters the area while the broadcast is live will
get the alert
</li>
</ul>
<p class="govuk-body heading-medium govuk-!-margin-bottom-6">
<a class="govuk-link govuk-link--no-visited-state" href='{{ url_for(".broadcast_tour", service_id=current_service.id, step_index=3) }}'>
How to try it out
</a>
</p>
</div>
<div class="govuk-grid-column-one-half">
<img src="{{ asset_url('images/broadcast-tour/2.png') }}" alt="">
<link rel="preload" href="{{ asset_url('images/broadcast-tour/3.png') }}" as="image">
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,43 @@
{% from "components/banner.html" import banner_wrapper %}
{% extends "admin_template.html" %}
{% block per_page_title %}
Step 3
{% endblock %}
{% set mainClasses = "govuk-!-padding-top-0 govuk-!-padding-bottom-0" %}
{% block content %}
<div class="banner-tour banner-tour-no-fixed-height govuk-!-margin-top-0">
<div class="govuk-grid-row">
<div class="govuk-grid-column-one-half">
<h1 class="heading-medium">
You have a trial account
</h1>
<ul>
<li>
Theres no risk of triggering a real, live broadcast
</li>
<li>
Get familiar with the system now, so youre ready to use it if
theres an emergency
</li>
<li>
When youre ready, apply for a live account
</li>
</ul>
<p class="govuk-body heading-medium">
<a class="govuk-link govuk-link--no-visited-state" href='{{ url_for(".service_dashboard", service_id=current_service.id) }}'>
Continue to dashboard
</a>
</p>
</div>
<div class="govuk-grid-column-one-half">
<img src="{{ asset_url('images/broadcast-tour/3.png') }}" alt="">
</div>
</div>
</div>
{% endblock %}

View File

@@ -94,6 +94,7 @@ def test_empty_broadcast_dashboard(
client_request,
service_one,
mock_get_no_broadcast_messages,
mock_get_service_templates_when_no_templates_exist,
):
service_one['permissions'] += ['broadcast']
page = client_request.get(
@@ -114,6 +115,7 @@ def test_broadcast_dashboard(
client_request,
service_one,
mock_get_broadcast_messages,
mock_get_service_templates,
):
service_one['permissions'] += ['broadcast']
page = client_request.get(

View File

@@ -319,6 +319,7 @@ def test_register_from_email_auth_invite(
mock_accept_invite,
mock_create_event,
mock_add_user_to_service,
mock_get_service,
invite_email_address,
):
sample_invite['auth_type'] = 'email_auth'
@@ -372,6 +373,7 @@ def test_can_register_email_auth_without_phone_number(
mock_accept_invite,
mock_create_event,
mock_add_user_to_service,
mock_get_service,
):
sample_invite['auth_type'] = 'email_auth'
with client.session_transaction() as session:

View File

@@ -178,6 +178,7 @@ def test_activate_user_redirects_to_service_dashboard_if_user_already_belongs_to
sample_invite,
api_user_active,
mock_login,
mock_get_service,
):
mocker.patch('app.user_api_client.add_user_to_service', side_effect=HTTPError(
response=Mock(