mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-04-28 05:01:06 -04:00
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:
27
app/assets/stylesheets/components/browse-list.scss
Normal file
27
app/assets/stylesheets/components/browse-list.scss
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,4 +9,10 @@
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.button {}
|
||||
|
||||
.button-destructive {
|
||||
@include button($error-colour)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
@import 'components/big-number';
|
||||
@import 'components/banner';
|
||||
@import 'components/textbox';
|
||||
@import 'components/browse-list';
|
||||
|
||||
@import 'views/job';
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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')
|
||||
|
||||
62
app/main/views/service_settings.py
Normal file
62
app/main/views/service_settings.py
Normal 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'))
|
||||
20
app/templates/components/browse-list.html
Normal file
20
app/templates/components/browse-list.html
Normal 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 %}
|
||||
11
app/templates/components/list.html
Normal file
11
app/templates/components/list.html
Normal 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 %}
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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() %}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
22
app/templates/views/service-settings/delete.html
Normal file
22
app/templates/views/service-settings/delete.html
Normal 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 %}
|
||||
22
app/templates/views/service-settings/name.html
Normal file
22
app/templates/views/service-settings/name.html
Normal 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 %}
|
||||
34
app/templates/views/service-settings/request-to-go-live.html
Normal file
34
app/templates/views/service-settings/request-to-go-live.html
Normal 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 %}
|
||||
33
app/templates/views/service-settings/status.html
Normal file
33
app/templates/views/service-settings/status.html
Normal 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 won’t 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 %}
|
||||
61
tests/app/main/views/test_service_settings.py
Normal file
61
tests/app/main/views/test_service_settings.py
Normal 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
|
||||
Reference in New Issue
Block a user