Add pages for ‘service settings’ flow

Adds the pages and wires them together, so that it’s possible to click
through them.

The wording is not quite English, but attempts to be an rough description of
what the consequences are for each of the four actions.
This commit is contained in:
Chris Hill-Scott
2016-01-07 12:29:56 +00:00
parent 750c23e805
commit 3989d1b576
20 changed files with 364 additions and 34 deletions

View File

@@ -0,0 +1,27 @@
.browse-list {
margin-bottom: $gutter;
&-item {
list-style: none;
margin-bottom: $gutter-two-thirds;
}
a.browse-list-link {
@include bold-24;
&-destructive,
&-destructive:visited {
@include bold-24;
color: $error-colour;
}
}
&-hint {
@include core-16;
margin-top: 5px;
}
}

View File

@@ -9,4 +9,10 @@
margin-left: 5px;
}
.button {}
.button-destructive {
@include button($error-colour)
}
}

View File

@@ -39,6 +39,7 @@
@import 'components/big-number';
@import 'components/banner';
@import 'components/textbox';
@import 'components/browse-list';
@import 'views/job';

View File

@@ -5,5 +5,5 @@ main = Blueprint('main', __name__)
from app.main.views import (
index, sign_in, sign_out, register, two_factor, verify, sms, add_service,
code_not_received, jobs, dashboard, templates
code_not_received, jobs, dashboard, templates, service_settings
)

View File

@@ -54,11 +54,6 @@ def manageusers():
return render_template('views/manage-users.html')
@main.route("/service-settings")
def servicesettings():
return render_template('views/service-settings.html')
@main.route("/api-keys")
def apikeys():
return render_template('views/api-keys.html')

View File

@@ -0,0 +1,62 @@
from flask import render_template, redirect, request, url_for
from flask_login import login_required
from app.main import main
service = {
'name': 'Service name',
'live': False,
'active': True
}
@main.route("/service-settings")
def service_settings():
return render_template(
'views/service-settings.html',
service=service
)
@main.route("/service-settings/name", methods=['GET', 'POST'])
def name():
if request.method == 'GET':
return render_template(
'views/service-settings/name.html',
service=service
)
elif request.method == 'POST':
return redirect(url_for('.service_settings'))
@main.route("/service-settings/request-to-go-live", methods=['GET', 'POST'])
def request_to_go_live():
if request.method == 'GET':
return render_template(
'views/service-settings/request-to-go-live.html',
service=service
)
elif request.method == 'POST':
return redirect(url_for('.service_settings'))
@main.route("/service-settings/status", methods=['GET', 'POST'])
def status():
if request.method == 'GET':
return render_template(
'views/service-settings/status.html',
service=service
)
elif request.method == 'POST':
return redirect(url_for('.service_settings'))
@main.route("/service-settings/delete", methods=['GET', 'POST'])
def delete():
if request.method == 'GET':
return render_template(
'views/service-settings/delete.html',
service=service
)
elif request.method == 'POST':
return redirect(url_for('.index'))

View File

@@ -0,0 +1,20 @@
{% macro browse_list(items) %}
{% if items %}
<nav class="browse-list">
<ul>
{% for item in items %}
{% if item.title and item.link %}
<li class="browse-list-item">
<a href="{{ item.link }}" class="browse-list-link{% if item.destructive %}-destructive{% endif %}">{{ item.title }}</a>
{% if item.hint %}
<div class="browse-list-hint">
{{ item.hint }}
</div>
{% endif %}
</li>
{% endif %}
{% endfor %}
</ul>
</nav>
{% endif %}
{% endmacro %}

View File

@@ -0,0 +1,11 @@
{% macro list(items) %}
{% if items %}
<ul class="list list-bullet">
{% for item in items %}
<li>
{{ item }}
</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}

View File

@@ -1,9 +1,9 @@
{% macro submit_form(button_text, back_link=False) %}
{% macro submit_form(button_text, back_link=False, back_link_text="Back", destructive=False) %}
<div class="submit-form">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input type="submit" class="button" value="{{ button_text }}" />
<input type="submit" class="button{% if destructive %}-destructive{% endif %}" value="{{ button_text }}" />
{% if back_link %}
<a class="submit-form-back-link" role="button" href="{{ back_link }}">Back</a>
<a class="submit-form-back-link" role="button" href="{{ back_link }}">{{ back_link_text }}</a>
{% endif %}
</div>
{% endmacro %}

View File

@@ -1,4 +1,4 @@
{% macro table(items, caption='', field_headings='', field_headings_visible=True, caption_visible=True) -%}
{% macro mapping_table(caption='', field_headings=[], field_headings_visible=True, caption_visible=True) -%}
<table class="table">
<caption class="heading-medium table-heading{{ ' visuallyhidden' if not caption_visible}}">
{{ caption }}
@@ -17,21 +17,34 @@
</tr>
</thead>
<tbody>
{% if items %}
{% for item in items %}
<tr class="table-row">
{{ caller(item) }}
</tr>
{% endfor %}
{% else %}
<p class="table-no-content">
{{ empty_message }}
</p>
{% endif %}
{{ caller() }}
</tbody>
</table>
{%- endmacro %}
{% macro list_table(items, caption='', empty_message='', field_headings=[], field_headings_visible=True, caption_visible=True) -%}
{% if items %}
{% set parent_caller = caller %}
{% call mapping_table(caption, field_headings, field_headings_visible, caption_visible) %}
{% for item in items %}
{% call row() %}
{{ parent_caller(item) }}
{% endcall %}
{% endfor %}
{%- endcall %}
{% else %}
<p class="summary-item-no-content">
{{ empty_message }}
</p>
{% endif %}
{%- endmacro %}
{% macro row() -%}
<tr class="table-row">
{{ caller() }}
</tr>
{%- endmacro %}
{% macro field(align='left', status='') -%}
<td class="table-field{% if align == 'right' %}-right-aligned{% endif %}">
<span class="{{ 'table-field-status-' + status if status }}">{{ caller() }}</span>

View File

@@ -10,7 +10,7 @@
</ul>
<ul>
<li><a href="{{ url_for('.manageusers') }}">Manage users</a></li>
<li><a href="{{ url_for('.servicesettings') }}">Service settings</a></li>
<li><a href="{{ url_for('.service_settings') }}">Service settings</a></li>
</ul>
<ul>
<li><a href="/user-profile">Your details</a></li>

View File

@@ -1,5 +1,5 @@
{% extends "withnav_template.html" %}
{% from "components/table.html" import table, field %}
{% from "components/table.html" import list_table, field %}
{% from "components/big-number.html" import big_number %}
{% block page_title %}
@@ -25,9 +25,10 @@
</li>
</ul>
{% call(item) table(
{% call(item) list_table(
jobs[:3],
caption="Recent text messages",
empty_message="No recent text messages",
field_headings=['Job', 'File', 'Time', 'Status']
) %}
{% call field() %}

View File

@@ -1,5 +1,5 @@
{% extends "withnav_template.html" %}
{% from "components/table.html" import 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/banner.html" import banner %}
@@ -41,7 +41,7 @@ GOV.UK Notify | Notifications activity
Sent with template <a href="{{ url_for('.edit_template') }}">{{ template_used }}</a> at {{ uploaded_file_time }}
</p>
{% call(item) table(
{% call(item) list_table(
messages,
caption='Messages',
caption_visible=False,

View File

@@ -1,5 +1,5 @@
{% extends "withnav_template.html" %}
{% from "components/table.html" import table, field %}
{% from "components/table.html" import list_table, field %}
{% block page_title %}
GOV.UK Notify | Notifications activity
@@ -9,7 +9,7 @@ GOV.UK Notify | Notifications activity
<h1 class="heading-xlarge">Notifications activity</h1>
{% call(item) table(
{% call(item) list_table(
jobs,
caption="Recent activity",
caption_visible=False,

View File

@@ -1,4 +1,5 @@
{% extends "withnav_template.html" %}
{% from "components/browse-list.html" import browse_list %}
{% block page_title %}
GOV.UK Notify | Service settings
@@ -6,12 +7,33 @@ GOV.UK Notify | Service settings
{% block maincolumn_content %}
<h1 class="heading-xlarge">Service settings</h1>
<p>Here's where users can update their service profile.</p>
<p><a href="dashboard">Back to dashboard</a></p>
<h1 class="heading-xlarge">Service settings</h1>
{{ browse_list([
{
'title': 'Rename service',
'link': url_for('.name'),
'hint': 'Your service is named “{}”'.format(service.name)
},
{
'title': 'Make service live',
'link': url_for('.request_to_go_live'),
'hint': 'A live service can send messages to anyone',
} if not service.live else {
},
{
'title': 'Stop sending messages',
'link': url_for('.status')
} if service.active else {
'title': 'Unsuspend service',
'link': url_for('.status')
},
{
'title': 'Delete everything',
'link': url_for('.delete'),
'hint': '',
'destructive': True
},
]) }}
{% endblock %}

View File

@@ -0,0 +1,22 @@
{% extends "withnav_template.html" %}
{% from "components/submit-form.html" import submit_form %}
{% block page_title %}
GOV.UK Notify | Service settings
{% endblock %}
{% block maincolumn_content %}
<h1 class="heading-xlarge">Delete this service</h1>
<p>
All will be lost.
</p>
<form method="post">
{{ submit_form('Delete', destructive=True) }}
</form>
<p><a href="{{ url_for('.service_settings') }}">Back to service settings</a></p>
{% endblock %}

View File

@@ -0,0 +1,22 @@
{% extends "withnav_template.html" %}
{% from "components/textbox.html" import textbox %}
{% from "components/submit-form.html" import submit_form %}
{% block page_title %}
GOV.UK Notify | Service settings
{% endblock %}
{% block maincolumn_content %}
<h1 class="heading-xlarge">Rename your service</h1>
<form method="post">
{{ textbox('new_name', 'New name', value=service.name) }}
{{ submit_form('Save') }}
</form>
<p><a href="{{ url_for('.service_settings') }}">Back to service settings</a></p>
{% endblock %}

View File

@@ -0,0 +1,34 @@
{% extends "withnav_template.html" %}
{% from "components/submit-form.html" import submit_form %}
{% from "components/list.html" import list %}
{% block page_title %}
GOV.UK Notify | Service settings
{% endblock %}
{% block maincolumn_content %}
<h1 class="heading-xlarge">Make your service live</h1>
<div class="grid-row">
<div class="column-two-thirds">
<p>
Before you can send messages to anyone, you need to:
</p>
{{ list([
"Have spoken to someone",
"Have permission from someone else",
"etc."
]) }}
<form method="post">
{{ submit_form("Request to go live") }}
</form>
<p><a href="{{ url_for('.service_settings') }}">Back to service settings</a></p>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,33 @@
{% extends "withnav_template.html" %}
{% from "components/submit-form.html" import submit_form %}
{% block page_title %}
GOV.UK Notify | Service settings
{% endblock %}
{% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">Suspend your service</h1>
<p>
Suspending a service means it wont send messages. Any messages that are
already queued will still be sent.
</p>
<p>
You can undo this at any time.
</p>
<form method="post">
{{ submit_form('Suspend') }}
</form>
<p><a href="{{ url_for('.service_settings') }}">Back to service settings</a></p>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,61 @@
def test_should_show_overview(notifications_admin):
response = notifications_admin.test_client().get('/service-settings')
assert response.status_code == 200
assert 'Service settings' in response.get_data(as_text=True)
def test_should_show_service_name(notifications_admin):
response = notifications_admin.test_client().get('/service-settings/name')
assert response.status_code == 200
assert 'Service name' in response.get_data(as_text=True)
def test_should_redirect_after_change_service_name(notifications_admin):
response = notifications_admin.test_client().post('/service-settings/request-to-go-live')
assert response.status_code == 302
assert 'http://localhost/service-settings' == response.location
def test_should_show_request_to_go_live(notifications_admin):
response = notifications_admin.test_client().get('/service-settings/request-to-go-live')
assert response.status_code == 200
assert 'Request to go live' in response.get_data(as_text=True)
def test_should_redirect_after_request_to_go_live(notifications_admin):
response = notifications_admin.test_client().post('/service-settings/request-to-go-live')
assert response.status_code == 302
assert 'http://localhost/service-settings' == response.location
def test_should_show_status_page(notifications_admin):
response = notifications_admin.test_client().get('/service-settings/status')
assert response.status_code == 200
assert 'Suspend your service' in response.get_data(as_text=True)
def test_should_show_redirect_after_status_change(notifications_admin):
response = notifications_admin.test_client().post('/service-settings/status')
assert response.status_code == 302
assert 'http://localhost/service-settings' == response.location
def test_should_show_delete_page(notifications_admin):
response = notifications_admin.test_client().get('/service-settings/delete')
assert response.status_code == 200
assert 'Delete service' in response.get_data(as_text=True)
def test_should_show_redirect_after_deleting_service(notifications_admin):
response = notifications_admin.test_client().post('/service-settings/delete')
assert response.status_code == 302
assert 'http://localhost/' == response.location