Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Onboarding prototype #5328

Draft
wants to merge 24 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e130627
Add banner on creation of user account
klssmith Nov 22, 2024
6737d8c
Update content on add new service page
klssmith Nov 22, 2024
a0c0c30
Add trial mode tag
klssmith Nov 22, 2024
527bed5
Add "Get ready to to live" link in left hand nav
klssmith Nov 22, 2024
9f1781f
Change "Your profile" to "Your account"
klssmith Nov 22, 2024
54f2460
Change "Switch services" to "Your services"
klssmith Nov 22, 2024
9de6eaa
Update content of email sender name page
klssmith Nov 22, 2024
fbf422f
Restyle go-live task list
klssmith Nov 25, 2024
daec27e
Add page to check if service is unique
klssmith Nov 25, 2024
0b287f2
Store result of confirming the service is unique
klssmith Nov 26, 2024
538861a
Add email sender changed check to go-live checklist
klssmith Nov 27, 2024
28dd2bf
Add link to add new reply-to address when choosing reply-to address
klssmith Nov 27, 2024
56e5297
Update estimate-usage page
kr8n3r Nov 27, 2024
7dc4217
Add page prompting user to add email-reply to address when sending
klssmith Nov 27, 2024
9fb474b
Show email sender name page as part of sending an email
klssmith Nov 29, 2024
0a54cfc
Use production header colour
klssmith Nov 29, 2024
68904da
Update content of "Trial mode" page
klssmith Dec 4, 2024
15c366f
Vary where back link for SMS senders page goes
klssmith Dec 4, 2024
078f724
Change links to and from email reply-to route from go-live page
klssmith Dec 5, 2024
b4ca53e
Change links to and from email reply-to route from sending journey
klssmith Dec 5, 2024
19254ff
Make backlinks from reply-to address verify page vary
klssmith Dec 5, 2024
eddc17a
Rename go-live URL and estimate usage URL
klssmith Dec 11, 2024
032ac3e
Remove request to go live content from service settings page
klssmith Dec 18, 2024
227658e
Stop logging out platform admin users after 30 mins
klssmith Jan 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/assets/javascripts/esm/all-esm.mjs
Original file line number Diff line number Diff line change
@@ -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, Checkboxes } from 'govuk-frontend';

import CollapsibleCheckboxes from './collapsible-checkboxes.mjs';
import FocusBanner from './focus-banner.mjs';
Expand All @@ -16,6 +16,8 @@ createAll(Radios);
createAll(ErrorSummary);
createAll(SkipLink);
createAll(Tabs);
createAll(NotificationBanner);
createAll(Checkboxes);

const $collapsibleCheckboxes = document.querySelector('[data-notify-module="collapsible-checkboxes"]');
if ($collapsibleCheckboxes) {
Expand Down
15 changes: 12 additions & 3 deletions app/assets/stylesheets/components/navigation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -74,7 +79,7 @@

box-sizing: border-box;
margin-bottom: govuk-spacing(1);

&:focus:before {
border-color: $govuk-focus-text-colour;
}
Expand Down Expand Up @@ -107,6 +112,10 @@
}
}

&-service-name {
margin-bottom: govuk-spacing(1);
}


a {
display: block;
Expand Down Expand Up @@ -148,4 +157,4 @@

}

}
}
3 changes: 3 additions & 0 deletions app/assets/stylesheets/govuk-frontend/_all.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ $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/components/tag/index";
@import "govuk/components/task-list/index";

@import "govuk/utilities";
@import "govuk/overrides";
Expand Down
3 changes: 1 addition & 2 deletions app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
6 changes: 3 additions & 3 deletions app/main/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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"),
],
)

Expand Down
19 changes: 19 additions & 0 deletions app/main/views/send.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down Expand Up @@ -249,6 +267,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),
)

Expand Down
108 changes: 102 additions & 6 deletions app/main/views/service_settings/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -128,23 +129,69 @@ def service_name_change(service_id):
)


@main.route("/services/<uuid:service_id>/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:
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)


@main.route("/services/<uuid:service_id>/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=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,
)

if form.validate_on_submit():
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))
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,
Expand Down Expand Up @@ -189,7 +236,7 @@ def service_data_retention(service_id):
)


@main.route("/services/<uuid:service_id>/service-settings/request-to-go-live/estimate-usage", methods=["GET", "POST"])
@main.route("/services/<uuid:service_id>/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(
Expand All @@ -214,10 +261,11 @@ def estimate_usage(service_id):
return render_template(
"views/service-settings/estimate-usage.html",
form=form,
error_summary_enabled=True,
)


@main.route("/services/<uuid:service_id>/service-settings/request-to-go-live", methods=["GET"])
@main.route("/services/<uuid:service_id>/get-ready-to-go-live", methods=["GET"])
@user_has_permissions("manage_service")
def request_to_go_live(service_id):
if current_service.live:
Expand All @@ -226,7 +274,7 @@ def request_to_go_live(service_id):
return render_template("views/service-settings/request-to-go-live.html")


@main.route("/services/<uuid:service_id>/service-settings/request-to-go-live", methods=["POST"])
@main.route("/services/<uuid:service_id>/get-ready-to-go-live", methods=["POST"])
@user_has_permissions("manage_service")
@user_is_gov_user
def submit_request_to_go_live(service_id):
Expand Down Expand Up @@ -404,6 +452,16 @@ def service_email_reply_to(service_id):
@main.route("/services/<uuid:service_id>/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")
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)

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
Expand Down Expand Up @@ -436,6 +494,8 @@ def service_add_email_reply_to(service_id):
service_id=service_id,
notification_id=notification_id,
is_default=is_default,
route=route,
template_id=template_id,
)
)

Expand All @@ -444,6 +504,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,
)


Expand All @@ -454,13 +515,31 @@ 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")
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,
template_id=template_id,
)


Expand All @@ -477,6 +556,16 @@ 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")
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)

if replace:
existing = current_service.get_email_reply_to_address(replace)
existing_is_default = existing["is_default"]
Expand Down Expand Up @@ -516,6 +605,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,
}
Expand Down Expand Up @@ -968,8 +1058,14 @@ def service_delete_letter_contact(service_id, letter_contact_id):
@main.route("/services/<uuid:service_id>/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,
)


Expand Down
Loading