From e1306273ce95163d7329d842680319e770551ffd Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Fri, 22 Nov 2024 10:09:10 +0000 Subject: [PATCH 01/24] Add banner on creation of user account This adds the notification banner from the design system when a user has logged in for the first time after creating a service. Still to do: - Work out if invited users see the banner too --- app/assets/javascripts/esm/all-esm.mjs | 3 ++- app/assets/stylesheets/govuk-frontend/_all.scss | 1 + app/main/views/verify.py | 4 ++-- app/main/views/your_services.py | 5 ++++- app/templates/views/your-services.html | 9 +++++++++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/esm/all-esm.mjs b/app/assets/javascripts/esm/all-esm.mjs index f575ece78b..9c25f678d4 100644 --- a/app/assets/javascripts/esm/all-esm.mjs +++ b/app/assets/javascripts/esm/all-esm.mjs @@ -1,5 +1,5 @@ // GOVUK Frontend modules -import { createAll, Header, Button, Radios, ErrorSummary, SkipLink, Tabs } from 'govuk-frontend'; +import { createAll, Header, Button, Radios, ErrorSummary, SkipLink, Tabs, NotificationBanner } from 'govuk-frontend'; import CollapsibleCheckboxes from './collapsible-checkboxes.mjs'; import FocusBanner from './focus-banner.mjs'; @@ -16,6 +16,7 @@ createAll(Radios); createAll(ErrorSummary); createAll(SkipLink); createAll(Tabs); +createAll(NotificationBanner); const $collapsibleCheckboxes = document.querySelector('[data-notify-module="collapsible-checkboxes"]'); if ($collapsibleCheckboxes) { diff --git a/app/assets/stylesheets/govuk-frontend/_all.scss b/app/assets/stylesheets/govuk-frontend/_all.scss index 1765e6473c..c0767a165c 100644 --- a/app/assets/stylesheets/govuk-frontend/_all.scss +++ b/app/assets/stylesheets/govuk-frontend/_all.scss @@ -24,6 +24,7 @@ $govuk-assets-path: "/static/"; @import "govuk/components/tabs/index"; @import "govuk/components/textarea/index"; @import "govuk/components/summary-list/index"; +@import "govuk/components/notification-banner/index"; @import "govuk/utilities"; @import "govuk/overrides"; diff --git a/app/main/views/verify.py b/app/main/views/verify.py index 802cc4684b..53b2d4b25b 100644 --- a/app/main/views/verify.py +++ b/app/main/views/verify.py @@ -82,9 +82,9 @@ def activate_user(user_id): return redirect(url_for("main.organisation_dashboard", org_id=organisation_id)) if user.default_organisation.can_ask_to_join_a_service: - return redirect(url_for("main.your_services")) + return redirect(url_for("main.your_services", new_user_account="yes")) - return redirect(url_for("main.add_service")) + return redirect(url_for("main.your_services", new_user_account="yes")) def _add_invited_user_to_service(invitation): diff --git a/app/main/views/your_services.py b/app/main/views/your_services.py index 798cbe403a..bee372f825 100644 --- a/app/main/views/your_services.py +++ b/app/main/views/your_services.py @@ -1,4 +1,4 @@ -from flask import redirect, render_template, session, url_for +from flask import redirect, render_template, request, session, url_for from flask_login import current_user from app import status_api_client @@ -21,6 +21,8 @@ def services_or_dashboard(): @main.route("/your-services") @user_is_logged_in def your_services(): + new_user_account = request.args.get("new_user_account") + org_count, live_service_count = None, None if current_user.platform_admin: org_count, live_service_count = ( @@ -32,6 +34,7 @@ def your_services(): can_add_service=current_user.is_gov_user, org_count=org_count, live_service_count=live_service_count, + new_user_account=new_user_account, ) diff --git a/app/templates/views/your-services.html b/app/templates/views/your-services.html index 8acb445ee1..056083d6e2 100644 --- a/app/templates/views/your-services.html +++ b/app/templates/views/your-services.html @@ -1,5 +1,6 @@ {% extends "withoutnav_template.html" %} {% from "govuk_frontend_jinja/components/button/macro.html" import govukButton %} +{% from "govuk_frontend_jinja/components/notification-banner/macro.html" import govukNotificationBanner %} {% macro service_list( heading, @@ -68,6 +69,14 @@

{% endblock %} {% block maincolumn_content %} + {% if new_user_account == 'yes' %} + {{ govukNotificationBanner({ + "titleText": "You have created a GOV.UK Notify account", + "text": "Add or join a service to start sending messages.", + "classes": "govuk-!-margin-top-7", + }) }} + {% endif %} +

Your {{ thing_to_choose_between }}

From 6737d8c59dea59562de718e309f04a22530a7f89 Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Fri, 22 Nov 2024 10:54:01 +0000 Subject: [PATCH 02/24] Update content on add new service page --- app/main/forms.py | 2 +- app/templates/views/add-service.html | 41 ++++++++++------------------ 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/app/main/forms.py b/app/main/forms.py index 0c4d755688..a173cb3fad 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -1292,7 +1292,7 @@ def populate(self, domains_list): class CreateServiceForm(StripWhitespaceForm): name = GovukTextInputField( - "Service name", + "Enter a service name", validators=[ DataRequired(message="Enter a service name"), MustContainAlphanumericCharacters(), diff --git a/app/templates/views/add-service.html b/app/templates/views/add-service.html index 881e0ffdd0..633e00fe89 100644 --- a/app/templates/views/add-service.html +++ b/app/templates/views/add-service.html @@ -4,12 +4,10 @@ {% from "components/form.html" import form_wrapper %} {% from "govuk_frontend_jinja/components/back-link/macro.html" import govukBackLink %} -{% set heading = 'Enter a service name' %} +{% set heading = 'Add a new service' %} {% block backLink %} - {% if request.args.get("back") == "your_services" %} - {{ govukBackLink({ "href": url_for('main.your_services') }) }} - {% endif %} + {{ govukBackLink({ "href": url_for('main.your_services') }) }} {% endblock %} {% block per_page_title %} @@ -20,39 +18,30 @@
{{ govuk_page_header(heading) }} -

This is the name your emails will come from.

-

You can also display it at the start of every text message you send.

- - {% if default_organisation_type == 'central' or default_organisation_type == 'local' %} -

Your service name should tell the recipient what your message is about, as well as who it’s from. For example:

- +

Give your service a name that describes the purpose of your messages.

+

You can change this later if you need to.

+

Do not include:

    - {% if default_organisation_type == 'central' %} -
  • Register to vote
  • -
  • Renew your Passport
  • -
  • Check your state pension
  • - {% elif default_organisation_type == 'local' %} -
  • School admissions - {{ current_user.default_organisation.name }}
  • -
  • Electoral services - {{ current_user.default_organisation.name }}
  • -
  • Blue Badge - {{ current_user.default_organisation.name }}
  • - {% endif %} +
  • acronyms, initialisms or abbreviations
  • +
  • your own name or the name of someone in your team
  • +
  • the name of a web application or back office system
- {% else %} -

Your service name should tell the recipient what your message is about, as well as who it’s from.

- {% endif %} - -

Do not use an acronym or initialism unless your users are already familiar with it.

{% call form_wrapper() %} - {{ form.name(param_extensions={"hint": {"text": "You can change this later"} }) }} + {{ form.name }} {% if not default_organisation_type %} {{ form.organisation_type }} {% endif %} - {{ page_footer('Add service') }} + {{ page_footer('Add a new service') }} {% endcall %} + {% if current_user.default_organisation.can_ask_to_join_a_service %} +

+ Check if you need to join an existing service instead +

+ {% endif %}
From a0c0c308fcd4754d3df342290ac3d2b5da16e4ec Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Fri, 22 Nov 2024 14:37:44 +0000 Subject: [PATCH 03/24] Add trial mode tag --- app/assets/stylesheets/components/navigation.scss | 15 ++++++++++++--- app/assets/stylesheets/govuk-frontend/_all.scss | 1 + app/templates/service_navigation.html | 12 ++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/components/navigation.scss b/app/assets/stylesheets/components/navigation.scss index a9667f18b8..a8f95ab1e5 100644 --- a/app/assets/stylesheets/components/navigation.scss +++ b/app/assets/stylesheets/components/navigation.scss @@ -7,10 +7,15 @@ $padding-bottom: 11px; &-service-name, - &-organisation-link { + &-organisation-link, + &-trial-tag { float: left; } + &-trial-tag { + margin-left: govuk-spacing(2); + } + &-service-type { @include govuk-font(16, $weight: bold); @@ -74,7 +79,7 @@ box-sizing: border-box; margin-bottom: govuk-spacing(1); - + &:focus:before { border-color: $govuk-focus-text-colour; } @@ -107,6 +112,10 @@ } } + &-service-name { + margin-bottom: govuk-spacing(1); + } + a { display: block; @@ -148,4 +157,4 @@ } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/govuk-frontend/_all.scss b/app/assets/stylesheets/govuk-frontend/_all.scss index c0767a165c..88ffefb401 100644 --- a/app/assets/stylesheets/govuk-frontend/_all.scss +++ b/app/assets/stylesheets/govuk-frontend/_all.scss @@ -25,6 +25,7 @@ $govuk-assets-path: "/static/"; @import "govuk/components/textarea/index"; @import "govuk/components/summary-list/index"; @import "govuk/components/notification-banner/index"; +@import "govuk/components/tag/index"; @import "govuk/utilities"; @import "govuk/overrides"; diff --git a/app/templates/service_navigation.html b/app/templates/service_navigation.html index e35bca7589..b1d46e92c2 100644 --- a/app/templates/service_navigation.html +++ b/app/templates/service_navigation.html @@ -1,3 +1,5 @@ +{% from "govuk_frontend_jinja/components/tag/macro.html" import govukTag %} + {% macro navigation_service_name(service) %} Switch service From 527bed52a9966fb96e37bf61acd0163c48443734 Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Fri, 22 Nov 2024 14:38:10 +0000 Subject: [PATCH 04/24] Add "Get ready to to live" link in left hand nav This is highlighted for pages which can only be reached via the go-live checklist. --- app/navigation.py | 16 +++++++++------- app/templates/main_nav.html | 3 +++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/navigation.py b/app/navigation.py index af8fc32375..da47b7976e 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -259,8 +259,6 @@ class MainNavigation(Navigation): "usage", }, "settings": { - "add_organisation_from_gp_service", - "add_organisation_from_nhs_local_service", "branding_nhs", "branding_option_preview", "email_branding_choose_banner_colour", @@ -273,17 +271,12 @@ class MainNavigation(Navigation): "email_branding_request_government_identity_logo", "email_branding_set_alt_text", "email_branding_upload_logo", - "estimate_usage", "letter_branding_options", "letter_branding_request", "link_service_to_organisation", - "request_to_go_live", "service_add_email_reply_to", "service_add_letter_contact", "service_add_sms_sender", - "service_agreement", - "service_accept_agreement", - "service_confirm_agreement", "service_confirm_delete_email_reply_to", "service_confirm_delete_letter_contact", "service_confirm_delete_sms_sender", @@ -336,6 +329,15 @@ class MainNavigation(Navigation): "org_member_make_service_live_check_unique", "org_member_make_service_live_contact_user", }, + "get-ready-to-go-live": { + "add_organisation_from_gp_service", + "add_organisation_from_nhs_local_service", + "estimate_usage", + "request_to_go_live", + "service_agreement", + "service_accept_agreement", + "service_confirm_agreement", + }, } diff --git a/app/templates/main_nav.html b/app/templates/main_nav.html index 6b6cd322d5..fbf8837b1d 100644 --- a/app/templates/main_nav.html +++ b/app/templates/main_nav.html @@ -27,6 +27,9 @@ {% endif %} + {% if current_service.trial_mode %} + + {% endif %} {% if current_user.can_make_service_live(current_service) %} {% endif %} From 9f1781fb6b7f10bb08c9e152ef80c53d34770b6e Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Fri, 22 Nov 2024 14:58:41 +0000 Subject: [PATCH 05/24] Change "Your profile" to "Your account" --- app/navigation.py | 2 +- app/templates/views/user-profile.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/navigation.py b/app/navigation.py index da47b7976e..3f603dc8d7 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -172,7 +172,7 @@ def visible_header_nav(self): nav_items.append( { "href": url_for("main.user_profile"), - "text": "Your profile", + "text": "Your account", "active": self.is_selected("user-profile"), } ) diff --git a/app/templates/views/user-profile.html b/app/templates/views/user-profile.html index ac55f6ec3f..90fc498a27 100644 --- a/app/templates/views/user-profile.html +++ b/app/templates/views/user-profile.html @@ -2,12 +2,12 @@ {% from "govuk_frontend_jinja/components/summary-list/macro.html" import govukSummaryList %} {% block per_page_title %} - Your profile + Your account {% endblock %} {% block maincolumn_content %} -

Your profile

+

Your account

{% if can_see_edit %} {% set email_address_row = From 54f24602f45b104d146a40cdcee0691c62e4c2a4 Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Fri, 22 Nov 2024 14:59:09 +0000 Subject: [PATCH 06/24] Change "Switch services" to "Your services" --- app/templates/org_template.html | 2 +- app/templates/service_navigation.html | 2 +- app/templates/views/platform-admin/_base_template.html | 2 +- app/templates/views/service-settings/service-already-live.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/templates/org_template.html b/app/templates/org_template.html index cc684b23a9..5c18f58308 100644 --- a/app/templates/org_template.html +++ b/app/templates/org_template.html @@ -17,7 +17,7 @@ {{ current_org.name }} - Switch service + Your services
diff --git a/app/templates/service_navigation.html b/app/templates/service_navigation.html index b1d46e92c2..7653fcc841 100644 --- a/app/templates/service_navigation.html +++ b/app/templates/service_navigation.html @@ -30,6 +30,6 @@ }) }} {% endif %}
- Switch service + Your services
{% endmacro %} diff --git a/app/templates/views/platform-admin/_base_template.html b/app/templates/views/platform-admin/_base_template.html index 9e92665256..96d3a4def1 100644 --- a/app/templates/views/platform-admin/_base_template.html +++ b/app/templates/views/platform-admin/_base_template.html @@ -10,7 +10,7 @@ Platform admin - Switch service + Your services
diff --git a/app/templates/views/service-settings/service-already-live.html b/app/templates/views/service-settings/service-already-live.html index 8b256f4eed..ffa6ba64c4 100644 --- a/app/templates/views/service-settings/service-already-live.html +++ b/app/templates/views/service-settings/service-already-live.html @@ -22,7 +22,7 @@ {% if prompt_to_switch_service %}

- Switch service + Your services if you want to make a different service live.

{% endif %} From 9de6eaa748839984cc006b32af8b6e684a85f023 Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Fri, 22 Nov 2024 15:23:43 +0000 Subject: [PATCH 07/24] Update content of email sender name page Still to do: - Once this is linked to from more pages the back link will need to go to the page you came from --- app/main/forms.py | 4 ++-- app/main/views/service_settings/index.py | 2 +- .../partials/preview-email-sender-name.html | 4 ++-- .../custom-email-sender-name.html | 23 ++++++++++--------- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/app/main/forms.py b/app/main/forms.py index a173cb3fad..8b32425445 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -1922,11 +1922,11 @@ class ServiceEmailSenderForm(StripWhitespaceForm): } use_custom_email_sender_name = OnOffField( - "Choose a sender name", + "", choices_for_error_message="same or custom", choices=[ + (True, "Enter an email sender name"), (False, "Use the name of your service"), - (True, "Enter a custom sender name"), ], ) diff --git a/app/main/views/service_settings/index.py b/app/main/views/service_settings/index.py index b6f2533d70..6515d5da3e 100644 --- a/app/main/views/service_settings/index.py +++ b/app/main/views/service_settings/index.py @@ -132,7 +132,7 @@ def service_name_change(service_id): @user_has_permissions("manage_service") def service_email_sender_change(service_id): form = ServiceEmailSenderForm( - use_custom_email_sender_name=current_service.custom_email_sender_name is not None, + use_custom_email_sender_name=True, custom_email_sender_name=current_service.custom_email_sender_name, ) diff --git a/app/templates/partials/preview-email-sender-name.html b/app/templates/partials/preview-email-sender-name.html index 16a41cf49b..fabfe0a4b5 100644 --- a/app/templates/partials/preview-email-sender-name.html +++ b/app/templates/partials/preview-email-sender-name.html @@ -1,4 +1,4 @@ {% set email_sender_name = email_sender_name or '' %} -{{ email_sender_name or 'Example' }}
-{{ email_sender_name|make_string_safe_for_email_local_part or 'example' }}@notifications.service.gov.uk +{{ email_sender_name or 'Example sender name' }}
+{{ email_sender_name|make_string_safe_for_email_local_part or 'example.sender.name' }}@notifications.service.gov.uk diff --git a/app/templates/views/service-settings/custom-email-sender-name.html b/app/templates/views/service-settings/custom-email-sender-name.html index ab825102a6..b0b7c37c25 100644 --- a/app/templates/views/service-settings/custom-email-sender-name.html +++ b/app/templates/views/service-settings/custom-email-sender-name.html @@ -4,7 +4,7 @@ {% from "components/form.html" import form_wrapper %} {% from "govuk_frontend_jinja/components/back-link/macro.html" import govukBackLink %} -{% set heading = 'Email sender name' %} +{% set heading = 'Choose an email sender name' %} {% block service_page_title %} {{ heading }} @@ -19,16 +19,17 @@
{{ page_header(heading) }} -

You should choose a sender name that tells people:

+

This is the name your emails will come from.

-
    -
  • who the email is from
  • -
  • what the email is about
  • -
+

We will convert your sender name into an email address for you.

-

Do not use an acronym or initialism unless your users are already familiar with it.

+

Your sender name should make it easy to tell:

+
    +
  • what the email is about
  • +
  • which service, team or organisation sent it
  • +
-

Adding a custom sender name will also change the email address for your service.

+

Do not use acronyms, initialisms or abbreviations unless your recipients already know them.

{% set default_email_sender_name_hint %} {% with email_sender_name = current_service.name %} @@ -55,13 +56,13 @@ {{ form.use_custom_email_sender_name(param_extensions={ "items": [ { - "hint": { - "html": default_email_sender_name_hint, + "conditional": { + "html": custom_email_sender_name_field_html, }, }, { "conditional": { - "html": custom_email_sender_name_field_html, + "html": default_email_sender_name_hint, }, }, ] From fbf422fd30038863af839ac19748e7382d66923a Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Mon, 25 Nov 2024 11:05:11 +0000 Subject: [PATCH 08/24] Restyle go-live task list Uses the GOV.UK Frontend task list styling and updates the content on the request to go live page. This updates the description of the tasks shown to have the new content. Still to do: - Add the new tasks that will now appear in the list --- .../stylesheets/govuk-frontend/_all.scss | 1 + app/templates/components/task-list.html | 25 +++++---- .../service-settings/request-to-go-live.html | 53 +++++++++++-------- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/app/assets/stylesheets/govuk-frontend/_all.scss b/app/assets/stylesheets/govuk-frontend/_all.scss index 88ffefb401..e79c252333 100644 --- a/app/assets/stylesheets/govuk-frontend/_all.scss +++ b/app/assets/stylesheets/govuk-frontend/_all.scss @@ -26,6 +26,7 @@ $govuk-assets-path: "/static/"; @import "govuk/components/summary-list/index"; @import "govuk/components/notification-banner/index"; @import "govuk/components/tag/index"; +@import "govuk/components/task-list/index"; @import "govuk/utilities"; @import "govuk/overrides"; diff --git a/app/templates/components/task-list.html b/app/templates/components/task-list.html index b445abf00d..20e8f60e90 100644 --- a/app/templates/components/task-list.html +++ b/app/templates/components/task-list.html @@ -1,17 +1,24 @@ {% macro task_list_item(completed, label, link) %} -
  • - {% set status_id = label | make_string_safe_for_id %} - {{ label }} - {% if completed %} - Completed - {% else %} - Not completed - {% endif %} +
  • {% endmacro %} {% macro task_list_wrapper() %} -
      +
        {{ caller() }}
      {% endmacro %} diff --git a/app/templates/views/service-settings/request-to-go-live.html b/app/templates/views/service-settings/request-to-go-live.html index 45cc2f2a9d..5132ec455f 100644 --- a/app/templates/views/service-settings/request-to-go-live.html +++ b/app/templates/views/service-settings/request-to-go-live.html @@ -3,41 +3,50 @@ {% from "components/page-header.html" import page_header %} {% from "components/page-footer.html" import page_footer %} {% from "components/task-list.html" import task_list_wrapper, task_list_item %} -{% from "govuk_frontend_jinja/components/back-link/macro.html" import govukBackLink %} {% block service_page_title %} - Before you request to go live -{% endblock %} - -{% block backLink %} - {{ govukBackLink({ "href": url_for('main.service_settings', service_id=current_service.id) }) }} + Get ready to go live {% endblock %} {% block maincolumn_content %}
      - {{ page_header('Before you request to go live') }} + {{ page_header('Get ready to go live') }} + +

      Your service is in trial mode.

      +

      Before you can go live you must:

      +
        +
      1. Review your settings.
      2. +
      3. Complete the tasks on this page.
      4. +
      + +

      When you’re ready, we’ll check that your service meets our terms of use.

      + +

      If it does, we’ll make your service live within one working day.

      + +

      Set up your service

      + {% call task_list_wrapper() %} {{ task_list_item( current_service.has_estimated_usage, - 'Tell us how many messages you expect to send', + 'Tell us what you expect to send', url_for('main.estimate_usage', service_id=current_service.id), ) }} {{ task_list_item( current_service.has_team_members_with_manage_service_permission, - 'Add a team member who can manage settings, team and usage', + 'Add a team member with the ‘manage settings’ permission', url_for('main.manage_users', service_id=current_service.id), ) }} {{ task_list_item( current_service.has_templates, - 'Add templates with examples of the content you plan to send', + 'Add templates with examples of your content', url_for('main.choose_template', service_id=current_service.id), ) }} {% if current_service.intending_to_send_email %} {{ task_list_item( current_service.has_email_reply_to_address, 'Add a reply-to email address', - url_for('main.service_email_reply_to', service_id=current_service.id), + url_for('main.service_add_email_reply_to', service_id=current_service.id), ) }} {% endif %} {% if ( @@ -50,14 +59,17 @@ url_for('main.service_sms_senders', service_id=current_service.id), ) }} {% endif %} - {% if current_service.able_to_accept_agreement %} - {{ task_list_item( - current_service.organisation.agreement_signed, - 'Accept our data processing and financial agreement', - url_for('main.service_agreement', service_id=current_service.id), - ) }} - {% endif %} {% endcall %} + {% if current_service.able_to_accept_agreement %} +

      Make sure your organisation can use GOV.UK Notify

      + {% call task_list_wrapper() %} + {{ task_list_item( + current_service.organisation.agreement_signed, + 'Accept our data processing and financial agreement', + url_for('main.service_agreement', service_id=current_service.id), + ) }} + {% endcall %} + {% endif %} {% if not current_user.is_gov_user %}

      Only team members with a government email address can request to go live. @@ -71,11 +83,8 @@ Your team has already sent a request to go live for this service.

      {% else %} -

      - When we receive your request we’ll get back to you by the end of the next working day. -

      {% call form_wrapper() %} - {{ page_footer('Request to go live') }} + {{ page_footer('Ready to go live') }} {% endcall %} {% endif %}
      From daec27eeba4b506a22a9086c013641a1770bfafd Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Mon, 25 Nov 2024 14:43:41 +0000 Subject: [PATCH 09/24] Add page to check if service is unique Still to do: - We need to actually record if the service is unique or not when the form is submitted. --- app/main/views/service_settings/index.py | 21 +++++++++ app/navigation.py | 1 + .../confirm-your-service-is-unique.html | 43 +++++++++++++++++++ .../service-settings/request-to-go-live.html | 5 +++ 4 files changed, 70 insertions(+) create mode 100644 app/templates/views/service-settings/confirm-your-service-is-unique.html diff --git a/app/main/views/service_settings/index.py b/app/main/views/service_settings/index.py index 6515d5da3e..85d65aedfb 100644 --- a/app/main/views/service_settings/index.py +++ b/app/main/views/service_settings/index.py @@ -128,6 +128,27 @@ def service_name_change(service_id): ) +@main.route("/services//get-ready-to-go-live/confirm-your-service-is-unique", methods=["GET", "POST"]) +@user_has_permissions("manage_service") +def service_confirm_unique(service_id): + form = RenameServiceForm(name=current_service.name) + + if form.validate_on_submit(): + try: + current_service.update(name=form.name.data) + except HTTPError as http_error: + if http_error.status_code == 400 and ( + error_message := service_api_client.parse_edit_service_http_error(http_error) + ): + form.name.errors.append(error_message) + else: + raise http_error + else: + return redirect(url_for(".request_to_go_live", service_id=service_id)) + + return render_template("views/service-settings/confirm-your-service-is-unique.html", form=form) + + @main.route("/services//service-settings/email-sender", methods=["GET", "POST"]) @user_has_permissions("manage_service") def service_email_sender_change(service_id): diff --git a/app/navigation.py b/app/navigation.py index 3f603dc8d7..77856944e3 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -337,6 +337,7 @@ class MainNavigation(Navigation): "service_agreement", "service_accept_agreement", "service_confirm_agreement", + "service_confirm_unique", }, } diff --git a/app/templates/views/service-settings/confirm-your-service-is-unique.html b/app/templates/views/service-settings/confirm-your-service-is-unique.html new file mode 100644 index 0000000000..dc4b526dd3 --- /dev/null +++ b/app/templates/views/service-settings/confirm-your-service-is-unique.html @@ -0,0 +1,43 @@ +{% extends "withnav_template.html" %} +{% from "components/govuk-page-header.html" import govuk_page_header %} +{% from "components/page-footer.html" import page_footer %} +{% from "components/form.html" import form_wrapper %} +{% from "govuk_frontend_jinja/components/back-link/macro.html" import govukBackLink %} + +{% block per_page_title %} + Confirm that your service is unique +{% endblock %} + +{% block backLink %} + {{ govukBackLink({ "href": url_for('main.request_to_go_live', service_id=current_service.id)}) }} +{% endblock %} + +{% block maincolumn_content %} + + {{ govuk_page_header("Confirm that your service is unique") }} + +

      Your service must be the only one of its kind in your organisation.

      + +

      Before you go live, check that your service name describes the purpose of your messages.

      + +

      This will help us to understand if your service is unique.

      + +

      Do not include:

      +
        +
      • acronyms, initialisms or abbreviations
      • +
      • your own name or the name of someone in your team
      • +
      • the name of a web application or back office system
      • +
      + + {% call form_wrapper() %} + {{ form.name }} + {{ page_footer('Confirm') }} + {% endcall %} + + {% if current_user.default_organisation.can_ask_to_join_a_service %} +

      + Check if you need to join an existing service instead +

      + {% endif %} + +{% endblock %} diff --git a/app/templates/views/service-settings/request-to-go-live.html b/app/templates/views/service-settings/request-to-go-live.html index 5132ec455f..06c20bb74b 100644 --- a/app/templates/views/service-settings/request-to-go-live.html +++ b/app/templates/views/service-settings/request-to-go-live.html @@ -27,6 +27,11 @@

      Set up your service

      {% call task_list_wrapper() %} + {{ task_list_item( + current_service.is_unique, + 'Confirm that your service is unique', + url_for('main.service_confirm_unique', service_id=current_service.id), + ) }} {{ task_list_item( current_service.has_estimated_usage, 'Tell us what you expect to send', From 0b287f246e4aafb13bf1623e61e08ce1e4b29a2c Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Tue, 26 Nov 2024 15:47:09 +0000 Subject: [PATCH 10/24] Store result of confirming the service is unique Stored in Redis since this is a prototype, and not as a new column on the services table. --- app/main/views/service_settings/index.py | 4 +++- app/models/service.py | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/main/views/service_settings/index.py b/app/main/views/service_settings/index.py index 85d65aedfb..d4b008e31c 100644 --- a/app/main/views/service_settings/index.py +++ b/app/main/views/service_settings/index.py @@ -28,7 +28,7 @@ create_archive_service_event, create_set_inbound_sms_on_event, ) -from app.extensions import zendesk_client +from app.extensions import redis_client, zendesk_client from app.main import json_updates, main from app.main.forms import ( AdminBillingDetailsForm, @@ -71,6 +71,7 @@ from app.models.letter_rates import LetterRates from app.models.organisation import Organisation from app.models.sms_rate import SMSRate +from app.notify_client import cache from app.utils import DELIVERED_STATUSES, FAILURE_STATUSES, SENDING_STATUSES from app.utils.constants import SIGN_IN_METHOD_TEXT_OR_EMAIL from app.utils.services import service_has_or_is_expected_to_send_x_or_more_notifications @@ -144,6 +145,7 @@ def service_confirm_unique(service_id): else: raise http_error else: + redis_client.set(f"{service_id}_is_unique", b"true", ex=cache.DEFAULT_TTL) return redirect(url_for(".request_to_go_live", service_id=service_id)) return render_template("views/service-settings/confirm-your-service-is-unique.html", form=form) diff --git a/app/models/service.py b/app/models/service.py index 20eb103f48..23d10f0f1a 100644 --- a/app/models/service.py +++ b/app/models/service.py @@ -5,6 +5,7 @@ from notifications_utils.serialised_model import SerialisedModelCollection from werkzeug.utils import cached_property +from app.extensions import redis_client from app.models import JSONModel from app.models.branding import EmailBranding, LetterBranding from app.models.contact_list import ContactLists @@ -407,10 +408,17 @@ def get_letter_contact_block(self, id): def volumes_by_channel(self): return {channel: getattr(self, f"volume_{channel}") for channel in ("email", "sms", "letter")} + @property + def is_unique(self): + if redis_client.get(f"{self.id}_is_unique"): + return True + return False + @property def go_live_checklist_completed(self): return all( ( + self.is_unique, any(self.volumes_by_channel.values()), self.has_team_members_with_manage_service_permission, self.has_templates, From 538861a0e2d3cb9234e2814c2111ade80cea2feb Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Wed, 27 Nov 2024 09:37:37 +0000 Subject: [PATCH 11/24] Add email sender changed check to go-live checklist This checks whether a user has visited the page to add an email sender and clicked "Save" even if they decided not to add one and to go with the default of the service name. The result of this is stored in Redis since this is a prototype. --- app/main/views/service_settings/index.py | 1 + app/models/service.py | 11 +++++++++++ .../views/service-settings/request-to-go-live.html | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/app/main/views/service_settings/index.py b/app/main/views/service_settings/index.py index d4b008e31c..3ed8a07247 100644 --- a/app/main/views/service_settings/index.py +++ b/app/main/views/service_settings/index.py @@ -163,6 +163,7 @@ def service_email_sender_change(service_id): new_sender = form.custom_email_sender_name.data if form.use_custom_email_sender_name.data else None current_service.update(custom_email_sender_name=new_sender) + redis_client.set(f"{service_id}_has_confirmed_email_sender", b"true", ex=cache.DEFAULT_TTL) return redirect(url_for(".service_settings", service_id=service_id)) diff --git a/app/models/service.py b/app/models/service.py index 23d10f0f1a..b1a0b845ed 100644 --- a/app/models/service.py +++ b/app/models/service.py @@ -296,6 +296,16 @@ def intending_to_send_sms(self): return self.has_sms_templates return self.volume_sms > 0 + @property + def has_confirmed_email_sender(self): + if redis_client.get(f"{self.id}_has_confirmed_email_sender"): + return True + return False + + @property + def needs_to_confirm_email_sender(self): + return self.intending_to_send_email and not self.has_confirmed_email_sender + @cached_property def email_reply_to_addresses(self): return service_api_client.get_reply_to_email_addresses(self.id) @@ -422,6 +432,7 @@ def go_live_checklist_completed(self): any(self.volumes_by_channel.values()), self.has_team_members_with_manage_service_permission, self.has_templates, + not self.needs_to_confirm_email_sender, not self.needs_to_add_email_reply_to_address, not self.needs_to_change_sms_sender, ) diff --git a/app/templates/views/service-settings/request-to-go-live.html b/app/templates/views/service-settings/request-to-go-live.html index 06c20bb74b..03d379f5d9 100644 --- a/app/templates/views/service-settings/request-to-go-live.html +++ b/app/templates/views/service-settings/request-to-go-live.html @@ -49,6 +49,11 @@

      Set up your service

      ) }} {% if current_service.intending_to_send_email %} {{ task_list_item( + current_service.has_confirmed_email_sender, + 'Choose an email sender name', + url_for('main.service_email_sender_change', service_id=current_service.id), + ) }} + {{ task_list_item( current_service.has_email_reply_to_address, 'Add a reply-to email address', url_for('main.service_add_email_reply_to', service_id=current_service.id), From 28dd2bfc6fb779394e6ccb84f6d6c515df9eda09 Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Wed, 27 Nov 2024 14:04:10 +0000 Subject: [PATCH 12/24] Add link to add new reply-to address when choosing reply-to address --- app/main/views/send.py | 1 + app/templates/views/templates/set-sender.html | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/app/main/views/send.py b/app/main/views/send.py index dcbe89d4ea..9ddc36402d 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -249,6 +249,7 @@ def set_sender(service_id, template_id): template_id=template_id, sender_context={"title": sender_context["title"], "description": sender_context["description"]}, option_hints=option_hints, + template_type=template.template_type, back_link=_get_set_sender_back_link(service_id, template), ) diff --git a/app/templates/views/templates/set-sender.html b/app/templates/views/templates/set-sender.html index 02d1a1ca48..e259c8252f 100644 --- a/app/templates/views/templates/set-sender.html +++ b/app/templates/views/templates/set-sender.html @@ -30,5 +30,14 @@
      {% endcall %}
    + {% if template_type == "email" and current_user.has_permissions('manage_service') %} + + {% endif %} {% endblock %} From 56e529709f2e23e765514b78b632681367c82d4a Mon Sep 17 00:00:00 2001 From: Jani Kraner Date: Wed, 27 Nov 2024 12:29:38 +0000 Subject: [PATCH 13/24] Update estimate-usage page Use checkboxes with conditional content to display input fields. Field validation remains as it was. If fields have value or if they contain the error we check the checkbox so that the field is display and error visible (if applicable) Prototype code as checkboxes are in the view and we don't validate if the submit without checking any. --- app/assets/javascripts/esm/all-esm.mjs | 3 +- app/main/views/service_settings/index.py | 1 + .../service-settings/estimate-usage.html | 83 ++++++++++++++----- 3 files changed, 66 insertions(+), 21 deletions(-) diff --git a/app/assets/javascripts/esm/all-esm.mjs b/app/assets/javascripts/esm/all-esm.mjs index 9c25f678d4..db8bb6d710 100644 --- a/app/assets/javascripts/esm/all-esm.mjs +++ b/app/assets/javascripts/esm/all-esm.mjs @@ -1,5 +1,5 @@ // GOVUK Frontend modules -import { createAll, Header, Button, Radios, ErrorSummary, SkipLink, Tabs, NotificationBanner } from 'govuk-frontend'; +import { createAll, Header, Button, Radios, ErrorSummary, SkipLink, Tabs, NotificationBanner, Checkboxes } from 'govuk-frontend'; import CollapsibleCheckboxes from './collapsible-checkboxes.mjs'; import FocusBanner from './focus-banner.mjs'; @@ -17,6 +17,7 @@ createAll(ErrorSummary); createAll(SkipLink); createAll(Tabs); createAll(NotificationBanner); +createAll(Checkboxes); const $collapsibleCheckboxes = document.querySelector('[data-notify-module="collapsible-checkboxes"]'); if ($collapsibleCheckboxes) { diff --git a/app/main/views/service_settings/index.py b/app/main/views/service_settings/index.py index 3ed8a07247..648a7caa3b 100644 --- a/app/main/views/service_settings/index.py +++ b/app/main/views/service_settings/index.py @@ -238,6 +238,7 @@ def estimate_usage(service_id): return render_template( "views/service-settings/estimate-usage.html", form=form, + error_summary_enabled=True, ) diff --git a/app/templates/views/service-settings/estimate-usage.html b/app/templates/views/service-settings/estimate-usage.html index ce336ef935..6d27fe46ef 100644 --- a/app/templates/views/service-settings/estimate-usage.html +++ b/app/templates/views/service-settings/estimate-usage.html @@ -4,9 +4,10 @@ {% from "components/page-header.html" import page_header %} {% from "components/page-footer.html" import page_footer %} {% from "govuk_frontend_jinja/components/back-link/macro.html" import govukBackLink %} +{% from "govuk_frontend_jinja/components/checkboxes/macro.html" import govukCheckboxes %} {% block service_page_title %} - Tell us how many messages you expect to send + What do you expect to send? {% endblock %} {% block backLink %} @@ -22,26 +23,68 @@

    Enter the number of messages you expect to send in the next year

    {% endcall %} - {% else %} - {{ page_header('Tell us how many messages you expect to send') }} {% endif %} - {% call form_wrapper() %} -
    - {{ form.volume_email(param_extensions={ - "classes": "govuk-!-width-one-half", - "hint": {"text": "For example, 50,000"}, - }) }} - {{ form.volume_sms(param_extensions={ - "classes": "govuk-!-width-one-half", - "hint": {"text": "For example, 50,000"}, - }) }} - {{ form.volume_letter(param_extensions={ - "classes": "govuk-!-width-one-half", - "hint": {"text": "For example, 50,000"}, - }) }} -
    - {{ page_footer('Continue') }} - {% endcall %} + {% call form_wrapper() %} + {% set emailHtml %} + {{ form.volume_email(param_extensions={ + "classes": "govuk-!-width-one-half", + "hint": {"text": "For example 50,000"}, + }) }} + {% endset %} + {% set smsHtml %} + {{ form.volume_sms(param_extensions={ + "classes": "govuk-!-width-one-half", + "hint": {"text": "For example 50,000"}, + }) }} + {% endset %} + {% set letterHtml %} + {{ form.volume_letter(param_extensions={ + "classes": "govuk-!-width-one-half", + "hint": {"text": "For example 50,000"}, + }) }} + {% endset %} + {{ govukCheckboxes({ + "name": "estimated-usage", + "fieldset": { + "legend": { + "text": "What do you expect to send?", + "isPageHeading": true, + "classes": "govuk-fieldset__legend--l" + }, + }, + "classes": "govuk-form-group--error" if form.errors, + "hint": { + "text": "Select all that apply." + }, + "items": [ + { + "value": "emails", + "text": "Emails", + "checked": true if ('volume_email' in form.errors or form.volume_email.data), + "conditional": { + "html": emailHtml + } + }, + { + "value": "sms", + "text": "Text messages", + "checked": true if ('volume_sms' in form.errors or form.volume_sms.data), + "conditional": { + "html": smsHtml + } + }, + { + "value": "letters", + "text": "Letters", + "checked": true if ('volume_letter' in form.errors or form.volume_letter.data), + "conditional": { + "html": letterHtml + } + } + ] + }) }} + {{ page_footer('Save') }} + {% endcall %}
    {% endblock %} From 7dc4217d471179068ebb506e381818b0ce38c52d Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Wed, 27 Nov 2024 15:58:03 +0000 Subject: [PATCH 14/24] Add page prompting user to add email-reply to address when sending This new page prompts someone who has no email reply-to addresses to set one up when sending an email template. We only showed the "Where should replies come back to?" page before if you had multiple reply-to addresses. This new version of the page is shown if you have none, but only to people with the manage settings permission, since others won't be able to make the change. --- app/main/views/send.py | 18 ++++++++ .../templates/set-first-email-sender.html | 43 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 app/templates/views/templates/set-first-email-sender.html diff --git a/app/main/views/send.py b/app/main/views/send.py index 9ddc36402d..18c12fc35b 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -187,6 +187,13 @@ def _should_show_set_sender_page(service_id, template) -> bool: sender_details = get_sender_details(service_id, template.template_type) + if ( + len(sender_details) == 0 + and template.template_type == "email" + and current_user.has_permissions("manage_service") + ): + return True + if len(sender_details) <= 1: return False @@ -212,6 +219,17 @@ def set_sender(service_id, template_id): if len(sender_details) == 1: session["sender_id"] = sender_details[0]["id"] + if ( + len(sender_details) == 0 + and template.template_type == "email" + and current_user.has_permissions("manage_service") + ): + return render_template( + "views/templates/set-first-email-sender.html", + template_id=template_id, + back_link=_get_set_sender_back_link(service_id, template), + ) + if len(sender_details) <= 1: return redirect_to_one_off diff --git a/app/templates/views/templates/set-first-email-sender.html b/app/templates/views/templates/set-first-email-sender.html new file mode 100644 index 0000000000..e93ed09945 --- /dev/null +++ b/app/templates/views/templates/set-first-email-sender.html @@ -0,0 +1,43 @@ +{% extends "withnav_template.html" %} +{% from "components/page-header.html" import page_header %} +{% from "govuk_frontend_jinja/components/button/macro.html" import govukButton %} +{% from "govuk_frontend_jinja/components/back-link/macro.html" import govukBackLink %} + +{% block service_page_title %} + Where should replies come back to? +{% endblock %} + +{% block backLink %} + {{ govukBackLink({ "href": back_link }) }} +{% endblock %} + +{% block maincolumn_content %} + {{ page_header('Where should replies come back to?') }} + +

    + Before you go live, you need to add at least one reply-to address so recipients can reply to your messages. +

    +

    + Emails with a reply-to address: +

    +
      +
    • are less likely to be labelled as spam
    • +
    • appear more trustworthy
    • +
    +

    + You can manage your reply-to email addresses at any time in settings. +

    + +

    + {{ govukButton({ + "element": "a", + "text": "Add a reply-to email address", + "href": url_for('main.service_add_email_reply_to', service_id=current_service.id) + }) }} +

    + +

    + I’ll do this later +

    + + {% endblock %} From 9fb474b5c26f2c2ae5cd2023347c2cd50bbdcaa3 Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Fri, 29 Nov 2024 11:03:11 +0000 Subject: [PATCH 15/24] Show email sender name page as part of sending an email The page to select an email sender name now gets shown after a user adds their first email template if they haven't already confirmed which email sender name they want to use. The back links on this page go to either the settings page or the templates page, depending on how you got to the page. --- app/main/views/service_settings/index.py | 25 ++++++++++++++++++- app/main/views/templates.py | 22 ++++++++++++++++ .../custom-email-sender-name.html | 2 +- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/app/main/views/service_settings/index.py b/app/main/views/service_settings/index.py index 648a7caa3b..dec5fcc347 100644 --- a/app/main/views/service_settings/index.py +++ b/app/main/views/service_settings/index.py @@ -154,6 +154,18 @@ def service_confirm_unique(service_id): @main.route("/services//service-settings/email-sender", methods=["GET", "POST"]) @user_has_permissions("manage_service") def service_email_sender_change(service_id): + came_from_template_page = request.args.get("came_from_template_page") + from_template_folder_id = request.args.get("from_template_folder_id") + + if came_from_template_page: + back_link = url_for( + "main.choose_template", + service_id=service_id, + template_folder_id=from_template_folder_id, + ) + else: + back_link = url_for("main.service_settings", service_id=service_id) + form = ServiceEmailSenderForm( use_custom_email_sender_name=True, custom_email_sender_name=current_service.custom_email_sender_name, @@ -165,10 +177,21 @@ def service_email_sender_change(service_id): current_service.update(custom_email_sender_name=new_sender) redis_client.set(f"{service_id}_has_confirmed_email_sender", b"true", ex=cache.DEFAULT_TTL) - return redirect(url_for(".service_settings", service_id=service_id)) + if came_from_template_page: + return redirect( + url_for( + "main.add_service_template", + service_id=service_id, + template_type="email", + template_folder_id=from_template_folder_id, + ) + ) + + return redirect(url_for("main.service_settings", service_id=service_id)) return render_template( "views/service-settings/custom-email-sender-name.html", + back_link=back_link, form=form, organisation_type=current_service.organisation_type, error_summary_enabled=True, diff --git a/app/main/views/templates.py b/app/main/views/templates.py index fd80c2e9d6..1d9533865d 100644 --- a/app/main/views/templates.py +++ b/app/main/views/templates.py @@ -636,6 +636,16 @@ def add_service_template(service_id, template_type, template_folder_id=None): ) ) + if _should_show_choose_email_sender_name_page(template_type, current_service, current_user): + return redirect( + url_for( + "main.service_email_sender_change", + service_id=service_id, + came_from_template_page="yes", + from_template_folder_id=template_folder_id, + ) + ) + form = get_template_form(template_type)() if form.validate_on_submit(): try: @@ -673,6 +683,18 @@ def add_service_template(service_id, template_type, template_folder_id=None): ) +def _should_show_choose_email_sender_name_page(template_type, service, user): + if ( + template_type == "email" + and not service.has_email_templates + and user.has_permissions("manage_service") + and not service.has_confirmed_email_sender + ): + return True + + return False + + def abort_403_if_not_admin_user(): if not current_user.platform_admin: abort(403) diff --git a/app/templates/views/service-settings/custom-email-sender-name.html b/app/templates/views/service-settings/custom-email-sender-name.html index b0b7c37c25..2f7445a9ec 100644 --- a/app/templates/views/service-settings/custom-email-sender-name.html +++ b/app/templates/views/service-settings/custom-email-sender-name.html @@ -11,7 +11,7 @@ {% endblock %} {% block backLink %} - {{ govukBackLink({ "href": url_for('main.service_settings', service_id=current_service.id) }) }} + {{ govukBackLink({ "href": back_link }) }} {% endblock %} {% block maincolumn_content %} From 0a54cfc33d1ee89b1fd77fad37301ef0f1d6367b Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Fri, 29 Nov 2024 15:11:24 +0000 Subject: [PATCH 16/24] Use production header colour Changes the header colour to the blue we use in production to avoid confusion for any participants who already use Notify. --- app/config.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/config.py b/app/config.py index f062c12aa4..923a9f7af3 100644 --- a/app/config.py +++ b/app/config.py @@ -37,8 +37,7 @@ class Config: INVITATION_EXPIRY_SECONDS = 3600 * 24 * 2 # 2 days - also set on api EMAIL_2FA_EXPIRY_SECONDS = 1800 # 30 Minutes - # mix(govuk-colour("dark-grey"), govuk-colour("mid-grey")) - HEADER_COLOUR = os.environ.get("HEADER_COLOUR", "#81878b") + HEADER_COLOUR = "#1d70b8" HTTP_PROTOCOL = os.environ.get("HTTP_PROTOCOL", "http") NOTIFY_APP_NAME = "admin" NOTIFY_LOG_LEVEL = "DEBUG" From 68904daa892cf4363ad033b029f9d344f183445f Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Wed, 4 Dec 2024 09:17:27 +0000 Subject: [PATCH 17/24] Update content of "Trial mode" page --- .../guidance/using-notify/trial-mode.html | 48 ++++++++----------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/app/templates/views/guidance/using-notify/trial-mode.html b/app/templates/views/guidance/using-notify/trial-mode.html index f4d9de8829..a8271d1a32 100644 --- a/app/templates/views/guidance/using-notify/trial-mode.html +++ b/app/templates/views/guidance/using-notify/trial-mode.html @@ -11,41 +11,33 @@

    Trial mode

    -

    When you add a new service it will start in trial mode. This lets you try out GOV.UK Notify for free, with a few restrictions.

    -

    While your service is in trial mode you can only:

    +

    When you add a new service it will start in trial mode.

    +

    Trial mode lets you test your service for free before you go live.

    +

    In trial mode you can only:

      -
    • send messages to yourself and other people in your team
    • +
    • send messages to yourself and your team
    • send {{ email_and_sms_daily_limit | message_count('email') }} per day
    • send {{ email_and_sms_daily_limit | message_count('sms') }} per day
    • create letter templates, but not send them
    -
    +

    GP surgeries cannot send any text messages in trial mode.

    - {% if current_service and current_service.trial_mode %} -

    - To remove these restrictions, you can request to go live.

    - {% else %} -

    - To remove these restrictions: -

    -
      -
    1. Sign in to Notify.
    2. -
    3. Go to the Settings page.
    4. -
    5. Select Request to go live.
    6. -
    - {% endif %} -

    - When we receive your request we’ll get back to you by the end of the next working day. -

    -

    Before you request to go live

    -

    You must:

    -
      -
    • add examples of the messages you want to send
    • -
    • update your settings so you’re ready to send and receive messages
    • -
    • accept our data processing and financial agreement
    • -
    - +

    How to make your service live

    + {% if current_service and current_service.trial_mode %} +
      +
    1. Complete the Get ready to go live task list.
    2. +
    3. Select Ready to go live.
    4. +
    + {% else %} +
      +
    1. Sign in to GOV.UK Notify
    2. +
    3. Complete the Get ready to go live task list.
    4. +
    5. Select Ready to go live.
    6. +
    + {% endif %} +

    We’ll make your service live within one working day.

    +

    If your organisation is new to GOV.UK Notify, we’ll ask you to accept our data processing and financial agreement.

    {% endblock %} From 15c366fe25f476cdb223a4e57521bea8de4d76a0 Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Wed, 4 Dec 2024 11:58:38 +0000 Subject: [PATCH 18/24] Vary where back link for SMS senders page goes This previously always went to the service settings page, but now goes back to the ready to go live page if that's where you came from. --- app/main/views/service_settings/index.py | 6 ++++++ .../views/service-settings/request-to-go-live.html | 2 +- app/templates/views/service-settings/sms-senders.html | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/main/views/service_settings/index.py b/app/main/views/service_settings/index.py index dec5fcc347..cd4acad920 100644 --- a/app/main/views/service_settings/index.py +++ b/app/main/views/service_settings/index.py @@ -1016,8 +1016,14 @@ def service_delete_letter_contact(service_id, letter_contact_id): @main.route("/services//service-settings/sms-sender", methods=["GET"]) @user_has_permissions("manage_service", "manage_api_keys") def service_sms_senders(service_id): + if request.args.get("back") == "go-live": + back_link = url_for("main.request_to_go_live", service_id=service_id) + else: + back_link = url_for("main.service_settings", service_id=service_id) + return render_template( "views/service-settings/sms-senders.html", + back_link=back_link, ) diff --git a/app/templates/views/service-settings/request-to-go-live.html b/app/templates/views/service-settings/request-to-go-live.html index 03d379f5d9..e14e3f71a2 100644 --- a/app/templates/views/service-settings/request-to-go-live.html +++ b/app/templates/views/service-settings/request-to-go-live.html @@ -66,7 +66,7 @@

    Set up your service

    {{ task_list_item( not current_service.sms_sender_is_govuk, 'Change your Text message sender ID', - url_for('main.service_sms_senders', service_id=current_service.id), + url_for('main.service_sms_senders', service_id=current_service.id, back="go-live"), ) }} {% endif %} {% endcall %} diff --git a/app/templates/views/service-settings/sms-senders.html b/app/templates/views/service-settings/sms-senders.html index ae74861c8e..173089e95d 100644 --- a/app/templates/views/service-settings/sms-senders.html +++ b/app/templates/views/service-settings/sms-senders.html @@ -9,7 +9,7 @@ {% endblock %} {% block backLink %} - {{ govukBackLink({ "href": url_for('main.service_settings', service_id=current_service.id) }) }} + {{ govukBackLink({ "href": back_link }) }} {% endblock %} {% block maincolumn_content %} From 078f724d4aa683595a07a6eb370f99880b62ea3c Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Thu, 5 Dec 2024 09:59:40 +0000 Subject: [PATCH 19/24] Change links to and from email reply-to route from go-live page If you get to the page to add a reply-to address from the go-live checklist, the back link on this page takes you back to the go-live checklist (instead of the default of the settings page). After you have added a reply-to address from the go-live checklist we now redirect you back to the go-live checklist (instead of the page to show all email reply-to addreses). If you are on the page where the email address is still being verified and click "back" twice you will be taken out of the go-live route, but this is an edge case and fine for the prototype. --- app/main/views/service_settings/index.py | 20 +++++++++++++++++++ .../email-reply-to/_verify-updates.html | 2 +- .../service-settings/email-reply-to/add.html | 2 +- .../email-reply-to/verify.html | 2 +- .../service-settings/request-to-go-live.html | 2 +- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/main/views/service_settings/index.py b/app/main/views/service_settings/index.py index cd4acad920..96734a0744 100644 --- a/app/main/views/service_settings/index.py +++ b/app/main/views/service_settings/index.py @@ -452,6 +452,13 @@ def service_email_reply_to(service_id): @main.route("/services//service-settings/email-reply-to/add", methods=["GET", "POST"]) @user_has_permissions("manage_service") def service_add_email_reply_to(service_id): + route = request.args.get("route") + + if route == "go_live": + back_link = url_for("main.request_to_go_live", service_id=service_id) + else: + back_link = url_for("main.service_email_reply_to", service_id=service_id) + form = ServiceReplyToEmailForm() first_email_address = current_service.count_email_reply_to_addresses == 0 is_default = first_email_address if first_email_address else form.is_default.data @@ -484,6 +491,7 @@ def service_add_email_reply_to(service_id): service_id=service_id, notification_id=notification_id, is_default=is_default, + route=route, ) ) @@ -492,6 +500,7 @@ def service_add_email_reply_to(service_id): form=form, first_email_address=first_email_address, error_summary_enabled=True, + back_link=back_link, ) @@ -502,6 +511,8 @@ def service_add_email_reply_to(service_id): def service_verify_reply_to_address(service_id, notification_id): replace = request.args.get("replace", False) is_default = request.args.get("is_default", False) + route = request.args.get("route") + return render_template( "views/service-settings/email-reply-to/verify.html", service_id=service_id, @@ -509,6 +520,7 @@ def service_verify_reply_to_address(service_id, notification_id): partials=get_service_verify_reply_to_address_partials(service_id, notification_id), replace=replace, is_default=is_default, + route=route, ) @@ -525,6 +537,13 @@ def get_service_verify_reply_to_address_partials(service_id, notification_id): replace = request.args.get("replace", False) replace = False if replace == "False" else replace existing_is_default = False + route = request.args.get("route") + + if route == "go_live": + continue_url = url_for("main.request_to_go_live", service_id=service_id) + else: + continue_url = url_for("main.service_email_reply_to", service_id=service_id) + if replace: existing = current_service.get_email_reply_to_address(replace) existing_is_default = existing["is_default"] @@ -564,6 +583,7 @@ def get_service_verify_reply_to_address_partials(service_id, notification_id): form=form, first_email_address=first_email_address, replace=replace, + continue_url=continue_url, ), "stop": 0 if verification_status == "pending" else 1, } diff --git a/app/templates/views/service-settings/email-reply-to/_verify-updates.html b/app/templates/views/service-settings/email-reply-to/_verify-updates.html index 78fb823363..69b31d0346 100644 --- a/app/templates/views/service-settings/email-reply-to/_verify-updates.html +++ b/app/templates/views/service-settings/email-reply-to/_verify-updates.html @@ -25,7 +25,7 @@ {{ govukButton({ "element": "a", "text": "Continue", - "href": url_for('main.service_email_reply_to', service_id=service_id) + "href": continue_url }) }}
    {% elif verification_status == "failure" %} diff --git a/app/templates/views/service-settings/email-reply-to/add.html b/app/templates/views/service-settings/email-reply-to/add.html index 56a39981a9..b5c8d056b3 100644 --- a/app/templates/views/service-settings/email-reply-to/add.html +++ b/app/templates/views/service-settings/email-reply-to/add.html @@ -9,7 +9,7 @@ {% endblock %} {% block backLink %} - {{ govukBackLink({ "href": url_for('main.service_email_reply_to', service_id=current_service.id) }) }} + {{ govukBackLink({ "href": back_link }) }} {% endblock %} {% block maincolumn_content %} diff --git a/app/templates/views/service-settings/email-reply-to/verify.html b/app/templates/views/service-settings/email-reply-to/verify.html index 886214055e..791749e694 100644 --- a/app/templates/views/service-settings/email-reply-to/verify.html +++ b/app/templates/views/service-settings/email-reply-to/verify.html @@ -19,7 +19,7 @@ {% block maincolumn_content %} {{ ajax_block( partials, - url_for('json_updates.service_verify_reply_to_address_updates', service_id=service_id, notification_id=notification_id, is_default=is_default, replace=replace), + url_for('json_updates.service_verify_reply_to_address_updates', service_id=service_id, notification_id=notification_id, is_default=is_default, replace=replace, route=route), 'status', finished=finished ) }} diff --git a/app/templates/views/service-settings/request-to-go-live.html b/app/templates/views/service-settings/request-to-go-live.html index e14e3f71a2..31c4f869a6 100644 --- a/app/templates/views/service-settings/request-to-go-live.html +++ b/app/templates/views/service-settings/request-to-go-live.html @@ -56,7 +56,7 @@

    Set up your service

    {{ task_list_item( current_service.has_email_reply_to_address, 'Add a reply-to email address', - url_for('main.service_add_email_reply_to', service_id=current_service.id), + url_for('main.service_add_email_reply_to', service_id=current_service.id, route='go_live'), ) }} {% endif %} {% if ( From b4ca53e1ca1ff97bdfd1cc59b892db18e8247d7f Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Thu, 5 Dec 2024 10:55:33 +0000 Subject: [PATCH 20/24] Change links to and from email reply-to route from sending journey If you get to the page to add a reply-to address from the route of sending an email, the back link takes you back to the page to set the sender. After you have added a reply-to address as part of the route of sending an email, you get taken to the page to send the email (if you've just added the first address) or to the page to set the sender (if you have multiple senders). --- app/main/views/service_settings/index.py | 9 +++++++++ .../views/service-settings/email-reply-to/verify.html | 2 +- .../views/templates/set-first-email-sender.html | 2 +- app/templates/views/templates/set-sender.html | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/main/views/service_settings/index.py b/app/main/views/service_settings/index.py index 96734a0744..5a8d28e36e 100644 --- a/app/main/views/service_settings/index.py +++ b/app/main/views/service_settings/index.py @@ -453,9 +453,12 @@ def service_email_reply_to(service_id): @user_has_permissions("manage_service") def service_add_email_reply_to(service_id): route = request.args.get("route") + template_id = request.args.get("template_id") if route == "go_live": back_link = url_for("main.request_to_go_live", service_id=service_id) + elif route == "send": + back_link = url_for("main.set_sender", service_id=service_id, template_id=template_id) else: back_link = url_for("main.service_email_reply_to", service_id=service_id) @@ -492,6 +495,7 @@ def service_add_email_reply_to(service_id): notification_id=notification_id, is_default=is_default, route=route, + template_id=template_id, ) ) @@ -512,6 +516,7 @@ def service_verify_reply_to_address(service_id, notification_id): replace = request.args.get("replace", False) is_default = request.args.get("is_default", False) route = request.args.get("route") + template_id = request.args.get("template_id") return render_template( "views/service-settings/email-reply-to/verify.html", @@ -521,6 +526,7 @@ def service_verify_reply_to_address(service_id, notification_id): replace=replace, is_default=is_default, route=route, + template_id=template_id, ) @@ -538,9 +544,12 @@ def get_service_verify_reply_to_address_partials(service_id, notification_id): replace = False if replace == "False" else replace existing_is_default = False route = request.args.get("route") + template_id = request.args.get("template_id") if route == "go_live": continue_url = url_for("main.request_to_go_live", service_id=service_id) + elif route == "send": + continue_url = url_for("main.set_sender", service_id=service_id, template_id=template_id) else: continue_url = url_for("main.service_email_reply_to", service_id=service_id) diff --git a/app/templates/views/service-settings/email-reply-to/verify.html b/app/templates/views/service-settings/email-reply-to/verify.html index 791749e694..51fff039fb 100644 --- a/app/templates/views/service-settings/email-reply-to/verify.html +++ b/app/templates/views/service-settings/email-reply-to/verify.html @@ -19,7 +19,7 @@ {% block maincolumn_content %} {{ ajax_block( partials, - url_for('json_updates.service_verify_reply_to_address_updates', service_id=service_id, notification_id=notification_id, is_default=is_default, replace=replace, route=route), + url_for('json_updates.service_verify_reply_to_address_updates', service_id=service_id, notification_id=notification_id, is_default=is_default, replace=replace, route=route, template_id=template_id), 'status', finished=finished ) }} diff --git a/app/templates/views/templates/set-first-email-sender.html b/app/templates/views/templates/set-first-email-sender.html index e93ed09945..af87025b5f 100644 --- a/app/templates/views/templates/set-first-email-sender.html +++ b/app/templates/views/templates/set-first-email-sender.html @@ -32,7 +32,7 @@ {{ govukButton({ "element": "a", "text": "Add a reply-to email address", - "href": url_for('main.service_add_email_reply_to', service_id=current_service.id) + "href": url_for('main.service_add_email_reply_to', service_id=current_service.id, route='send', template_id=template_id) }) }}

    diff --git a/app/templates/views/templates/set-sender.html b/app/templates/views/templates/set-sender.html index e259c8252f..984d5c8621 100644 --- a/app/templates/views/templates/set-sender.html +++ b/app/templates/views/templates/set-sender.html @@ -34,7 +34,7 @@ From 19254ff07c765e825c489574e6982e3d3bc7018a Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Thu, 5 Dec 2024 12:05:55 +0000 Subject: [PATCH 21/24] Make backlinks from reply-to address verify page vary The links were going to the right place ('.service_add_email_reply_to'), but if we want to go back multiple times then the query parameters need to be passed through. --- app/main/views/service_settings/index.py | 13 +++++++++++++ .../service-settings/email-reply-to/verify.html | 8 +------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/app/main/views/service_settings/index.py b/app/main/views/service_settings/index.py index 5a8d28e36e..7d78fbd216 100644 --- a/app/main/views/service_settings/index.py +++ b/app/main/views/service_settings/index.py @@ -518,11 +518,24 @@ def service_verify_reply_to_address(service_id, notification_id): route = request.args.get("route") template_id = request.args.get("template_id") + if replace: + back_link = url_for("main.service_edit_email_reply_to", service_id=service_id, reply_to_email_id=replace) + elif route: + back_link = url_for( + "main.service_add_email_reply_to", + service_id=service_id, + route=route, + template_id=template_id, + ) + else: + back_link = url_for("main.service_add_email_reply_to", service_id=service_id, route=route) + return render_template( "views/service-settings/email-reply-to/verify.html", service_id=service_id, notification_id=notification_id, partials=get_service_verify_reply_to_address_partials(service_id, notification_id), + back_link=back_link, replace=replace, is_default=is_default, route=route, diff --git a/app/templates/views/service-settings/email-reply-to/verify.html b/app/templates/views/service-settings/email-reply-to/verify.html index 51fff039fb..d04f0b4db2 100644 --- a/app/templates/views/service-settings/email-reply-to/verify.html +++ b/app/templates/views/service-settings/email-reply-to/verify.html @@ -7,13 +7,7 @@ {% endblock %} {% block backLink %} - {% if replace %} - {% set back_link_href = url_for('main.service_edit_email_reply_to', service_id=service_id, reply_to_email_id=replace) %} - {% else %} - {% set back_link_href = url_for('main.service_add_email_reply_to', service_id=service_id) %} - {% endif %} - - {{ govukBackLink({ "href": back_link_href }) }} + {{ govukBackLink({ "href": back_link }) }} {% endblock %} {% block maincolumn_content %} From eddc17a8efe929baacf35de37afb1e741b75051b Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Wed, 11 Dec 2024 11:28:44 +0000 Subject: [PATCH 22/24] Rename go-live URL and estimate usage URL --- app/main/views/service_settings/index.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/main/views/service_settings/index.py b/app/main/views/service_settings/index.py index 7d78fbd216..3088248f3d 100644 --- a/app/main/views/service_settings/index.py +++ b/app/main/views/service_settings/index.py @@ -236,7 +236,7 @@ def service_data_retention(service_id): ) -@main.route("/services//service-settings/request-to-go-live/estimate-usage", methods=["GET", "POST"]) +@main.route("/services//get-ready-to-go-live/what-do-you-expect-to-send", methods=["GET", "POST"]) @user_has_permissions("manage_service") def estimate_usage(service_id): form = EstimateUsageForm( @@ -265,7 +265,7 @@ def estimate_usage(service_id): ) -@main.route("/services//service-settings/request-to-go-live", methods=["GET"]) +@main.route("/services//get-ready-to-go-live", methods=["GET"]) @user_has_permissions("manage_service") def request_to_go_live(service_id): if current_service.live: @@ -274,7 +274,7 @@ def request_to_go_live(service_id): return render_template("views/service-settings/request-to-go-live.html") -@main.route("/services//service-settings/request-to-go-live", methods=["POST"]) +@main.route("/services//get-ready-to-go-live", methods=["POST"]) @user_has_permissions("manage_service") @user_is_gov_user def submit_request_to_go_live(service_id): From 032ac3e1a45421e7ea7598037cee8246204ca15f Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Wed, 18 Dec 2024 15:30:12 +0000 Subject: [PATCH 23/24] Remove request to go live content from service settings page --- app/templates/views/service-settings.html | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/app/templates/views/service-settings.html b/app/templates/views/service-settings.html index 9f1f8a63a7..4ec5c0fd0b 100644 --- a/app/templates/views/service-settings.html +++ b/app/templates/views/service-settings.html @@ -469,28 +469,7 @@

    Letter settings

    - {% if current_service.trial_mode %} -

    Your service is in trial mode

    - -

    You can only:

    - -
      -
    • send messages to yourself and other people in your team
    • -
    • send {{ current_service.email_message_limit | message_count('email') }} per day
    • -
    • send {{ current_service.sms_message_limit | message_count('sms') }} per day
    • -
    • create letter templates, but not send them
    • -
    - -

    - {% if current_user.has_permissions('manage_service') %} - To remove these restrictions, you can send us a - request to go live. - {% else %} - Your service manager can ask to have these restrictions removed. - {% endif %} -

    - - {% else %} + {% if current_service.live %}

    Your service is live

    You can send up to: From 227658e148fe3ca799f993a7365e91954055685c Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Tue, 7 Jan 2025 14:47:08 +0000 Subject: [PATCH 24/24] Stop logging out platform admin users after 30 mins This is purely to help when running user research sessions, and not a change we want to make in other environments. --- app/notify_session.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/notify_session.py b/app/notify_session.py index ee47f0073d..9400861891 100644 --- a/app/notify_session.py +++ b/app/notify_session.py @@ -1,4 +1,4 @@ -from datetime import UTC, datetime, timedelta +from datetime import UTC, datetime from flask import Flask, Request, Response, request from flask.sessions import SecureCookieSession, SecureCookieSessionInterface @@ -17,10 +17,7 @@ def _get_inactive_session_expiry(self, app, session_start: datetime): """ absolute_expiration = session_start + app.permanent_session_lifetime - if current_user and current_user.platform_admin: - refresh_duration = timedelta(seconds=app.config["PLATFORM_ADMIN_INACTIVE_SESSION_TIMEOUT"]) - else: - refresh_duration = app.permanent_session_lifetime + refresh_duration = app.permanent_session_lifetime return min(datetime.now(UTC) + refresh_duration, absolute_expiration)