From b303e06ca09a85979522d5125dcdd4cb8dfa7b92 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Mon, 11 Jan 2016 11:13:06 +0000 Subject: [PATCH 01/10] Add a styleguide page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are now quite a few frontend components in the app. It’s good to have a reference for them to: - document for developers what patterns are available and how they are used - check for regressions - when working on one variation of a pattern you can check that your changes don’t break other variations of it - when changing the arguments to a pattern you can check that this doesn’t change the expected arguments already in use This commit adds a single page (`/_styleguide`) which has examples of all the patterns. --- app/main/__init__.py | 2 +- app/main/views/styleguide.py | 7 + app/templates/views/styleguide.html | 162 ++++++++++++++++++++++++ tests/app/main/views/test_styleguide.py | 4 + 4 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 app/main/views/styleguide.py create mode 100644 app/templates/views/styleguide.html create mode 100644 tests/app/main/views/test_styleguide.py diff --git a/app/main/__init__.py b/app/main/__init__.py index 3d3ab5cde..578ea5e92 100644 --- a/app/main/__init__.py +++ b/app/main/__init__.py @@ -4,5 +4,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, service_settings, forgot_password, new_password + code_not_received, jobs, dashboard, templates, service_settings, forgot_password, new_password, styleguide ) diff --git a/app/main/views/styleguide.py b/app/main/views/styleguide.py new file mode 100644 index 000000000..516a39b6c --- /dev/null +++ b/app/main/views/styleguide.py @@ -0,0 +1,7 @@ +from flask import render_template +from app.main import main + + +@main.route('/_styleguide') +def styleguide(): + return render_template('views/styleguide.html') diff --git a/app/templates/views/styleguide.html b/app/templates/views/styleguide.html new file mode 100644 index 000000000..9ad7ba9a3 --- /dev/null +++ b/app/templates/views/styleguide.html @@ -0,0 +1,162 @@ +{% extends "admin_template.html" %} + +{% from "components/banner.html" import banner %} +{% from "components/big-number.html" import big_number %} +{% from "components/browse-list.html" import browse_list %} +{% from "components/page-footer.html" import page_footer %} +{% from "components/sms-message.html" import sms_message, message_status %} +{% from "components/table.html" import mapping_table, list_table, row, field %} +{% from "components/textbox.html" import textbox %} + +{% block page_title %} + Styleguide – GOV.UK Notify +{% endblock %} + +{% block fullwidth_content %} + +

+ Styleguide +

+ +

Banner

+

Used to show the result of a user’s action.

+ {{ banner("This is a banner") }} + +

Big number

+ +

Used to show some important statistics.

+ +
+
+ {{ big_number("567") }} +
+
+ {{ big_number("2", "Messages delivered") }} +
+
+ +

Browse list

+ +

Used to navigate to child pages.

+ + {{ browse_list([ + { + 'title': 'Change your username', + 'link': 'http://example.com', + }, + { + 'title': 'Change your password', + 'link': 'http://example.com', + 'hint': 'Your password is used to log in' + }, + { + 'title': 'Delete everything', + 'link': 'http://example.com', + 'hint': 'You can’t undo this', + 'destructive': True + } + ]) }} + +

Page footer

+ +

+ Used to submit forms and optionally provide a link to go back to the + previous page. +

+

+ Must be used inside a form. +

+

+ Adds a hidden CSRF token to the page. +

+ + {{ page_footer( + button_text='Save and continue' + ) }} + + {{ page_footer( + button_text='Delete', destructive=True + ) }} + + {{ page_footer( + button_text='Send', back_link='http://example.com', back_link_text="Back to dashboard" + ) }} + +

SMS message

+ +

Used to show or preview an SMS message.

+ +
+
+ {{ sms_message("Your vehicle tax for LC12 BFL is due on 1 March 2016. Renew online at www.gov.uk/vehicle-tax") }} + {{ sms_message("Your vehicle tax for ((registration number)) is due on ((date)). Renew online at www.gov.uk/vehicle-tax") }} + {{ sms_message( + "Your vehicle tax for registration number is due on date. Renew online at www.gov.uk/vehicle-tax", + "+44 7700 900 306" + ) }} +
+
+ +

Message status

+
+
+ {{ message_status("Delivered 10:20") }} +
+
+ +

Tables

+ + {% call mapping_table( + caption='Account settings', + field_headings=['Label', 'Value'], + field_headings_visible=True, + caption_visible=True + ) %} + {% call row() %} + {% call field() %} + Username + {% endcall %} + {% call field() %} + admin + {% endcall %} + {% endcall %} + {% endcall %} + + {% call(item) list_table( + [ + { + 'file': 'dispatch_20151114.csv', 'status': 'Queued' + }, + { + 'file': 'dispatch_20151117.csv', 'status': 'Delivered' + }, + { + 'file': 'remdinder_monday.csv', 'status': 'Delivered' + } + ], + caption='Messages', + field_headings=['File', 'Status'], + field_headings_visible=False, + caption_visible=True + ) %} + {% call field() %} + {{ item.file }} + {% endcall %} + {% call field() %} + {{ item.status }} + {% endcall %} + {% endcall %} + +

Textbox

+ + {{ textbox('name', 'Username') }} + {{ textbox('password', 'Password', password=True) }} + {{ textbox( + 'message', + "Message", + value="Your vehicle tax for ((registration number)) is due on ((date)). Renew online at www.gov.uk/vehicle-tax", + small=False, + highlight_tags=True + ) }} + +{% endblock %} diff --git a/tests/app/main/views/test_styleguide.py b/tests/app/main/views/test_styleguide.py new file mode 100644 index 000000000..10004b847 --- /dev/null +++ b/tests/app/main/views/test_styleguide.py @@ -0,0 +1,4 @@ +def test_styleguide_can_render(notifications_admin): + response = notifications_admin.test_client().get('/_styleguide') + + assert response.status_code == 200 From 85b0b4af215fb9c757dd3b2b7588ff79ec311a40 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Mon, 11 Jan 2016 11:27:42 +0000 Subject: [PATCH 02/10] Replace `message_status` component with `banner` Message status was almost identical to banner, visually and semantically. This consolidates the two into one component. This means adding an extra parameter which controls whether or not the banner has a tick (with and without a tick are the only two variations currently). --- app/assets/stylesheets/components/banner.scss | 10 +++++++- .../stylesheets/components/sms-message.scss | 23 ------------------- app/templates/components/banner.html | 6 +++-- app/templates/components/sms-message.html | 8 ------- app/templates/views/job.html | 2 +- app/templates/views/notification.html | 5 +++- app/templates/views/styleguide.html | 16 ++++++------- 7 files changed, 25 insertions(+), 45 deletions(-) diff --git a/app/assets/stylesheets/components/banner.scss b/app/assets/stylesheets/components/banner.scss index a801b2ec7..70555d2d1 100644 --- a/app/assets/stylesheets/components/banner.scss +++ b/app/assets/stylesheets/components/banner.scss @@ -1,14 +1,22 @@ +%banner, .banner { @include core-19; background: $turquoise; color: $white; display: block; - padding: $gutter-half $gutter; + padding: $gutter-half; margin: 0 0 $gutter 0; text-align: center; position: relative; +} + +.banner-with-tick { + + @extend %banner; + padding: $gutter-half $gutter; + &:before { @include core-24; content: '✔'; diff --git a/app/assets/stylesheets/components/sms-message.scss b/app/assets/stylesheets/components/sms-message.scss index 4fa727388..abdd5f9bf 100644 --- a/app/assets/stylesheets/components/sms-message.scss +++ b/app/assets/stylesheets/components/sms-message.scss @@ -45,27 +45,4 @@ margin: -$gutter-half 0 $gutter 0; } - &-history { - - background: $turquoise; - color: $white; - padding: $gutter-half; - @include bold-19; - margin: 0 0 $gutter 0; - - &-heading { - - @include bold-19; - margin: 0; - - &-time { - @include inline-block; - margin-left: 10px; - font-weight: normal; - } - - } - - } - } diff --git a/app/templates/components/banner.html b/app/templates/components/banner.html index 2dab12c5d..a03d2cb0a 100644 --- a/app/templates/components/banner.html +++ b/app/templates/components/banner.html @@ -1,3 +1,5 @@ -{% macro banner(body) %} - +{% macro banner(body, with_tick=False) %} +
+ {{ body }} +
{% endmacro %} diff --git a/app/templates/components/sms-message.html b/app/templates/components/sms-message.html index 38d30b877..d0d0f92ce 100644 --- a/app/templates/components/sms-message.html +++ b/app/templates/components/sms-message.html @@ -10,11 +10,3 @@

{% endif %} {% endmacro %} - -{% macro message_status(status, time) %} -
-

- {{ status }} {{ time }} -

-
-{% endmacro %} diff --git a/app/templates/views/job.html b/app/templates/views/job.html index 29ae57ba7..b733a5e61 100644 --- a/app/templates/views/job.html +++ b/app/templates/views/job.html @@ -14,7 +14,7 @@ GOV.UK Notify | Notifications activity

- {{ banner(flash_message) }} + {{ banner(flash_message, with_tick=True) }}

-
- {{ form.hidden_tag() }} - {{ render_field(form.service_name, class='form-control-2-3') }} + + {{ textbox(form.service_name) }}

diff --git a/app/templates/views/edit-template.html b/app/templates/views/edit-template.html index 46615c78e..30ab1ba95 100644 --- a/app/templates/views/edit-template.html +++ b/app/templates/views/edit-template.html @@ -11,8 +11,8 @@ GOV.UK Notify | Edit template

{{ h1 }}

- {{ textbox(name='template_name', label='Template name', value=template_name) }} - {{ textbox(name='template_body', label='Message', small=False, value=template_body, highlight_tags=True) }} + {{ textbox(form.template_name) }} + {{ textbox(form.template_body, highlight_tags=True) }} {{ page_footer( 'Save and continue', back_link=url_for('.dashboard'), diff --git a/app/templates/views/email-not-received.html b/app/templates/views/email-not-received.html index 9f7960383..0ef40ffce 100644 --- a/app/templates/views/email-not-received.html +++ b/app/templates/views/email-not-received.html @@ -1,4 +1,5 @@ {% extends "admin_template.html" %} +{% from "components/textbox.html" import textbox %} {% from "components/page-footer.html" import page_footer %} {% block page_title %} @@ -14,13 +15,10 @@ GOV.UK Notify

Check your email address is correct and then resend the confirmation code.

- - {{ form.hidden_tag() }} - {{ render_field(form.email_address, class='form-control-2-3') }} - Your email address must end in .gov.uk -

-

- {{ page_footer('Resend confirmation code') }} + + {{ textbox(form.email_address) }} + Your email address must end in .gov.uk + {{ page_footer('Resend confirmation code') }}
diff --git a/app/templates/views/forgot-password.html b/app/templates/views/forgot-password.html index 4d36f2a86..c4062e6b9 100644 --- a/app/templates/views/forgot-password.html +++ b/app/templates/views/forgot-password.html @@ -1,4 +1,6 @@ {% extends "admin_template.html" %} +{% from "components/textbox.html" import textbox %} +{% from "components/page-footer.html" import page_footer %} {% block page_title %} GOV.UK Notify @@ -12,13 +14,11 @@ GOV.UK Notify

If you have forgotten your password, we can send you an email to create a new password.

-
- {{ form.hidden_tag() }} - {{ render_field(form.email_address, class='form-control-2-3') }} -

- -

+ + {{ textbox(form.email_address) }} + {{ page_footer("Send email") }}
+ diff --git a/app/templates/views/new-password.html b/app/templates/views/new-password.html index 580325410..16c098cb9 100644 --- a/app/templates/views/new-password.html +++ b/app/templates/views/new-password.html @@ -1,4 +1,6 @@ {% extends "admin_template.html" %} +{% from "components/textbox.html" import textbox %} +{% from "components/page-footer.html" import page_footer %} {% block page_title %} GOV.UK Notify @@ -13,17 +15,9 @@ GOV.UK Notify

You can now create a new password for your account.

-
- {{ form.hidden_tag() }} -

- {{ render_field(form.new_password, class="form-control-1-4", type="password") }} - Your password must have at least 10 characters -

- -

- -

- + + {{ textbox(form.new_password, hint="Your password must have at least 10 characters") }} + {{ page_footer("Continue") }}
{% else %} Message about email address does not exist. Some one needs to figure out the words here. diff --git a/app/templates/views/register.html b/app/templates/views/register.html index f640ac116..9bb45a3a8 100644 --- a/app/templates/views/register.html +++ b/app/templates/views/register.html @@ -1,4 +1,5 @@ {% extends "admin_template.html" %} +{% from "components/textbox.html" import textbox %} {% from "components/page-footer.html" import page_footer %} {% block page_title %} @@ -16,12 +17,10 @@ GOV.UK Notify | Create an account
{{ form.hidden_tag() }} - {{ render_field(form.name, class='form-control-2-3') }} - {{ render_field(form.email_address, class='form-control-2-3') }} - Your email address must end in .gov.uk - {{ render_field(form.mobile_number, class='form-control-2-3') }} - {{ render_field(form.password, class='form-control-2-3') }} - Your password must have at least 10 characters + {{ textbox(form.name) }} + {{ textbox(form.email_address, hint="Your email address must end in .gov.uk") }} + {{ textbox(form.mobile_number) }} + {{ textbox(form.password, hint="Your password must have at least 10 characters") }} {{ page_footer("Continue") }}
diff --git a/app/templates/views/service-settings/confirm.html b/app/templates/views/service-settings/confirm.html index fe0cd05c9..20206724c 100644 --- a/app/templates/views/service-settings/confirm.html +++ b/app/templates/views/service-settings/confirm.html @@ -14,7 +14,7 @@ GOV.UK Notify | Service settings
- {{ textbox('new_name', 'Enter your password', password=True) }} + {{ textbox(form.password) }} {{ page_footer( 'Confirm', destructive=destructive, diff --git a/app/templates/views/service-settings/name.html b/app/templates/views/service-settings/name.html index a86fdba2d..91de3d7ca 100644 --- a/app/templates/views/service-settings/name.html +++ b/app/templates/views/service-settings/name.html @@ -13,12 +13,15 @@ GOV.UK Notify | Service settings
-

- Your service name ({{ service.name }}) is included in every sent notification -

+

Users will see your service name:

+ +
    +
  • at the start of every text message, eg ‘Vehicle tax: we received your payment, thank you’
  • +
  • as your email sender name
  • +
- {{ textbox('new_name', 'New name', value=service.name) }} + {{ textbox(form.service_name) }} {{ page_footer( 'Save', back_link=url_for('.service_settings') diff --git a/app/templates/views/signin.html b/app/templates/views/signin.html index 870b61755..fe6210b0b 100644 --- a/app/templates/views/signin.html +++ b/app/templates/views/signin.html @@ -1,4 +1,5 @@ {% extends "admin_template.html" %} +{% from "components/textbox.html" import textbox %} {% from "components/page-footer.html" import page_footer %} {% block page_title %} @@ -13,14 +14,10 @@ Sign in

If you do not have an account, you can register for one now.

- - {{ form.hidden_tag() }} - {{ render_field(form.email_address, class='form-control-2-3') }} - {{ render_field(form.password, class='form-control-2-3') }} -

- Forgotten password? -

- {{ page_footer("Continue") }} + + {{ textbox(form.email_address) }} + {{ textbox(form.password) }} + {{ page_footer("Continue", back_link="#", back_link_text="Forgotten password?") }}
diff --git a/app/templates/views/styleguide.html b/app/templates/views/styleguide.html index fadbf0a4c..0caefd563 100644 --- a/app/templates/views/styleguide.html +++ b/app/templates/views/styleguide.html @@ -148,15 +148,8 @@ {% endcall %}

Textbox

- - {{ textbox('name', 'Username') }} - {{ textbox('password', 'Password', password=True) }} - {{ textbox( - 'message', - "Message", - value="Your vehicle tax for ((registration number)) is due on ((date)). Renew online at www.gov.uk/vehicle-tax", - small=False, - highlight_tags=True - ) }} + {{ textbox(form.username) }} + {{ textbox(form.password) }} + {{ textbox(form.message, highlight_tags=True) }} {% endblock %} diff --git a/app/templates/views/text-not-received.html b/app/templates/views/text-not-received.html index 529193617..f11a051fc 100644 --- a/app/templates/views/text-not-received.html +++ b/app/templates/views/text-not-received.html @@ -1,4 +1,5 @@ {% extends "admin_template.html" %} +{% from "components/textbox.html" import textbox %} {% from "components/page-footer.html" import page_footer %} {% block page_title %} @@ -13,9 +14,8 @@ GOV.UK Notify

Check your mobile phone number is correct and then resend the confirmation code.

-
- {{ form.hidden_tag() }} - {{ render_field(form.mobile_number, class='form-control-2-3') }} + + {{ textbox(form.mobile_number) }} {{ page_footer("Resend confirmation code") }}
diff --git a/app/templates/views/two-factor.html b/app/templates/views/two-factor.html index 46724c617..44cd98739 100644 --- a/app/templates/views/two-factor.html +++ b/app/templates/views/two-factor.html @@ -1,4 +1,5 @@ {% extends "admin_template.html" %} +{% from "components/textbox.html" import textbox %} {% from "components/page-footer.html" import page_footer %} {% block page_title %} @@ -14,9 +15,8 @@ GOV.UK Notify | Text verification

We've sent you a text message with a verification code.

-
- {{ form.hidden_tag() }} - {{ render_field(form.sms_code, class='form-control-1-4') }} + + {{ textbox(form.sms_code) }} I haven't received a text {{ page_footer("Continue") }}
diff --git a/app/templates/views/verify.html b/app/templates/views/verify.html index 94e594d1a..7c4c41180 100644 --- a/app/templates/views/verify.html +++ b/app/templates/views/verify.html @@ -1,4 +1,5 @@ {% extends "admin_template.html" %} +{% from "components/textbox.html" import textbox %} {% from "components/page-footer.html" import page_footer %} {% block page_title %} @@ -13,11 +14,10 @@ GOV.UK Notify | Confirm email address and mobile number

We've sent you confirmation codes by email and text message. You need to enter both codes here.

-
- {{ form.hidden_tag() }} - {{ render_field(form.email_code, class='form-control-1-4') }} + + {{ textbox(form.email_code) }} I haven't received an email - {{ render_field(form.sms_code, class='form-control-1-4') }} + {{ textbox(form.sms_code) }} I haven't received a text {{ page_footer("Continue") }}
From 362b2aeba7d288e00ed5efac8bc1335a89a07ce4 Mon Sep 17 00:00:00 2001 From: Martyn Inglis Date: Mon, 11 Jan 2016 17:00:04 +0000 Subject: [PATCH 06/10] New script to run db updates so can be done by ubuntu user --- appspec.yml | 4 ++++ scripts/aws_db_updates.sh | 3 +++ 2 files changed, 7 insertions(+) create mode 100755 scripts/aws_db_updates.sh diff --git a/appspec.yml b/appspec.yml index 56488949b..f5ac38fd8 100644 --- a/appspec.yml +++ b/appspec.yml @@ -13,6 +13,10 @@ hooks: location: scripts/aws_change_ownership.sh runas: root timeout: 300 + - + location: scripts/aws_db_updates.sh + runas: ubuntu + timeout: 300 ApplicationStart: - location: scripts/aws_start_app.sh diff --git a/scripts/aws_db_updates.sh b/scripts/aws_db_updates.sh new file mode 100755 index 000000000..e45ecc843 --- /dev/null +++ b/scripts/aws_db_updates.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +python3 db.py db upgrade From 35b4f8f3a77f6dba00d2b1c2605c936d681ef88c Mon Sep 17 00:00:00 2001 From: Martyn Inglis Date: Mon, 11 Jan 2016 17:23:10 +0000 Subject: [PATCH 07/10] Removed the db upgrades --- scripts/aws_install_dependencies.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/aws_install_dependencies.sh b/scripts/aws_install_dependencies.sh index e36fae522..a74b4ccea 100755 --- a/scripts/aws_install_dependencies.sh +++ b/scripts/aws_install_dependencies.sh @@ -4,4 +4,3 @@ echo "Install dependencies" cd /home/ubuntu/notifications-admin; export FLASK_CONFIG=/home/ubuntu/config.cfg pip3 install -r /home/ubuntu/notifications-admin/requirements.txt -python3 db.py db upgrade From e075145945da2e888943cd395a44ad9bb98c61f5 Mon Sep 17 00:00:00 2001 From: Martyn Inglis Date: Mon, 11 Jan 2016 17:32:24 +0000 Subject: [PATCH 08/10] Putting this back in the dependencies file for now - this fails on the instance and not sure why, putting back till I can figure it out --- appspec.yml | 6 +----- scripts/aws_db_updates.sh | 3 --- scripts/aws_install_dependencies.sh | 1 + 3 files changed, 2 insertions(+), 8 deletions(-) delete mode 100755 scripts/aws_db_updates.sh diff --git a/appspec.yml b/appspec.yml index f5ac38fd8..c6a713089 100644 --- a/appspec.yml +++ b/appspec.yml @@ -13,11 +13,7 @@ hooks: location: scripts/aws_change_ownership.sh runas: root timeout: 300 - - - location: scripts/aws_db_updates.sh - runas: ubuntu - timeout: 300 - ApplicationStart: + ApplicationStart: - location: scripts/aws_start_app.sh runas: root diff --git a/scripts/aws_db_updates.sh b/scripts/aws_db_updates.sh deleted file mode 100755 index e45ecc843..000000000 --- a/scripts/aws_db_updates.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -python3 db.py db upgrade diff --git a/scripts/aws_install_dependencies.sh b/scripts/aws_install_dependencies.sh index a74b4ccea..e36fae522 100755 --- a/scripts/aws_install_dependencies.sh +++ b/scripts/aws_install_dependencies.sh @@ -4,3 +4,4 @@ echo "Install dependencies" cd /home/ubuntu/notifications-admin; export FLASK_CONFIG=/home/ubuntu/config.cfg pip3 install -r /home/ubuntu/notifications-admin/requirements.txt +python3 db.py db upgrade From 840185017c48efa5005acbb717e93bb8cd6df7f9 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Tue, 12 Jan 2016 09:38:55 +0000 Subject: [PATCH 09/10] Add badges for requirements and code coverage --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 984842c8e..214b2fca5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -[![Build Status](https://api.travis-ci.org/alphagov/notifications-admin.svg?branch=master)](https://api.travis-ci.org/alphagov/notifications-admin.svg?branch=master) +[![Build Status](https://travis-ci.org/alphagov/notifications-admin.svg)](https://travis-ci.org/alphagov/notifications-admin) +[![Coverage Status](https://coveralls.io/repos/alphagov/notifications-admin/badge.svg?branch=master&service=github)](https://coveralls.io/github/alphagov/notifications-admin?branch=master) +[![Requirements Status](https://requires.io/github/alphagov/notifications-admin/requirements.svg?branch=master)](https://requires.io/github/alphagov/notifications-admin/requirements/?branch=master) # notifications-admin From 003c7e097a0435f415631969fecbcbe08ea2526e Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Tue, 12 Jan 2016 09:47:35 +0000 Subject: [PATCH 10/10] Remove badge for code coverage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It needs more integration, which I’m not sure we want at the moment. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 214b2fca5..0f963d9c5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ [![Build Status](https://travis-ci.org/alphagov/notifications-admin.svg)](https://travis-ci.org/alphagov/notifications-admin) -[![Coverage Status](https://coveralls.io/repos/alphagov/notifications-admin/badge.svg?branch=master&service=github)](https://coveralls.io/github/alphagov/notifications-admin?branch=master) [![Requirements Status](https://requires.io/github/alphagov/notifications-admin/requirements.svg?branch=master)](https://requires.io/github/alphagov/notifications-admin/requirements/?branch=master)