Removed all govuk css (#2814)

* Removed all govuk css

* Updated reference files

* Removing govuk js

* Fixed casing for modules, removed unused page

* Got more reference images

* Updated template page

* Removed govuk padding util

* Updated hint to uswds hint

* More govuk cleanup

* Commiting backstopjs ref files

* Fixed all unit tests that broke due to brittleness around govuk styling

* Added new ref images

* Final removal of govuk

* Officially removed all govuk references

* Updated reference file

* Updated link to button

* UI modernization

* Cleanup

* removed govuk escaping tests since they are no longer needed

* Fix CodeQL security issue in escapeElementName function

- Escape backslashes first before other special characters
- Prevents potential double-escaping vulnerability
- Addresses CodeQL alert about improper string escaping

* Found more govuk removal. Fixed unit tests

* Add missing pipeline check to pre-commit

* updated test

* Updated e2e test

* More update to e2e test

* Fixed another e2e test

* Simple PR comments addressed

* More updates

* Updated backstop ref files

* Refactored folder selection for non-admins

* Updated redundant line

* Updated tests to include correct mocks

* Added more ref files

* Addressing carlos comments

* Addressing Carlo comments, cleanup of window initing

* More cleanup and addressing carlo comments

* Fixing a11 scan

* Fixed a few issues with javascript

* Fixed for pr

* Fixing e2e tests

* Tweaking e2e test

* Added more ref files and cleaned up urls.js

* Fixed bug with creating new template

* Removed brittle test - addressed code ql comment

* e2e race condition fix

* More e2e test fixes

* Updated e2e tests to not wait for text sent

* Updated test to not wait for button click response

* Made tear down more resilent if staging is down

* reverted e2e test to what was working before main merge

* Updated backstopRef images

* Updated gulp to include job-polling differently
This commit is contained in:
Alex Janousek
2025-10-06 09:38:54 -04:00
committed by GitHub
parent a366a10865
commit 6f5750f095
323 changed files with 2731 additions and 2796 deletions

View File

@@ -19,7 +19,7 @@
) }}
<p>
This accessibility statement applies to the Notify.gov domain. <!-- It does not apply to the <a class="usa-link" href="https://docs.notifications.service.gov.uk">Notify.gov API documentation subdomain</a>.-->
This accessibility statement applies to the Notify.gov domain. For GSA's accessibility statement, visit <a href="https://www.gsa.gov/website-information/accessibility-statement">https://www.gsa.gov/website-information/accessibility-statement</a>.
</p>
<p>
@@ -167,7 +167,7 @@
</h3>
<p>
The following content on the <a class="usa-link" href="https://status.notifications.service.gov.uk/">Notify status page</a> is not compliant with the WCAG version 2.1 AA standard:
The following content on the Notify status page is not compliant with the WCAG version 2.1 AA standard:
</p>
<ul class="usa-list">

View File

@@ -15,7 +15,7 @@
{% block maincolumn_content %}
{{ page_header('Callbacks') }}
<div class="table-overflow-x-auto">
<div class="bottom-gutter-3-2 dashboard-table body-copy-table table-overflow-x-auto">
<div class="margin-bottom-3 dashboard-table body-copy-table table-overflow-x-auto">
{% call mapping_table(
caption='General',
field_headings=['Label', 'Value', 'Action'],

View File

@@ -8,7 +8,7 @@
{% block maincolumn_content %}
<h1 class="heading-medium bottom-gutter-3-2">
<h1 class="font-heading-lg margin-bottom-3">
API integration
</h1>
@@ -26,7 +26,7 @@
<div class="grid-row">
<div class="grid-col-6">
<h2 class="heading-small">
<h2 class="font-heading-md">
Message log
</h2>
</div>
@@ -46,11 +46,16 @@
</div>
{% endif %}
{% for notification in api_notifications.notifications %}
<details class="api-notifications-item govuk-details" data-module="govuk-details">
<summary class="govuk-details__summary api-notifications-item__heading">
<h3>
<span class="govuk-details__summary-text">
{{ notification.to }}
<div class="usa-accordion api-notifications-item">
<h3 class="usa-accordion__heading">
<button
type="button"
class="usa-accordion__button api-notifications-item__heading"
aria-expanded="false"
aria-controls="notification-accordion-{{ notification.id }}"
>
<span>
{{ notification.to }}
</span>
<span class="grid-row api-notifications-item__meta">
<span class="grid-col-6 api-notifications-item__meta-key">
@@ -62,9 +67,9 @@
</time>
</span>
</span>
</h3>
</summary>
<div class="govuk-details__text api-notifications-item__data">
</button>
</h3>
<div id="notification-accordion-{{ notification.id }}" class="usa-accordion__content api-notifications-item__data" hidden>
<dl id="notification-{{ notification.id }}">
{% for key in [
'id', 'client_reference', 'notification_type', 'created_at', 'updated_at', 'sent_at', 'status'
@@ -77,7 +82,7 @@
<a class="usa-link" href="{{ url_for('.view_notification', service_id=current_service.id, notification_id=notification.id) }}">View {{ 1|message_count_label(notification.template.template_type, suffix='') }}</a>
</dl>
</div>
</details>
</div>
{% endfor %}
{% if api_notifications.notifications %}
<div class="api-notifications-item">

View File

@@ -31,7 +31,7 @@
{% call field() %}
<div class="file-list">
{{ item.name }}
<div class="hint">
<div class="usa-hint">
{% if item.key_type == 'normal' %}
Live sends to anyone
{% elif item.key_type == 'team' %}
@@ -44,7 +44,7 @@
{% endcall %}
{% if item.expiry_date %}
{% call field(align='right') %}
<span class='hint'>Revoked {{ item.expiry_date|format_datetime_table }}</span>
<span class='usa-hint'>Revoked {{ item.expiry_date|format_datetime_table }}</span>
{% endcall %}
{% else %}
{% call field(align='right', status='error') %}

View File

@@ -20,7 +20,7 @@
You will not be able to see it again once you leave this page.
</p>
<div class="bottom-gutter-2">
<div class="margin-bottom-3">
{{ copy_to_clipboard(
'{}-{}-{}'.format(key_name, service_id, secret),

View File

@@ -67,7 +67,7 @@ Error
<div class="usa-alert usa-alert--error" role="alert">
<div class="usa-alert__body">
<h1 class="usa-alert__heading banner-title" data-module="track-error" data-error-type="Missing recipient columns"
data-error-label="{{ upload_id }}">Theres a problem with your column names</h1>
data-error-label="{{ upload_id }}">There's a problem with your column names</h1>
<p class="usa-alert-text">
Your file needs a column called {{ first_recipient_column }}.
</p>
@@ -85,7 +85,7 @@ Error
<div class="usa-alert usa-alert--error" role="alert">
<div class="usa-alert__body">
<h1 class="usa-alert__heading banner-title" data-module="track-error" data-error-type="Duplicate recipient columns"
data-error-label="{{ upload_id }}">Theres a problem with your column names</h1>
data-error-label="{{ upload_id }}">There's a problem with your column names</h1>
<p class="usa-alert__text">
We found more than one column called {{ (
recipients.duplicate_recipient_column_headers

View File

@@ -20,7 +20,7 @@
{{ page_header('Select delivery time') }}
{{ template|string }}
<div class="bottom-gutter-3-2">
<div class="margin-bottom-3">
{# Alert for users of AT #}
<span id="upload-success" class="usa-sr-only">File uploaded successfully</span>
<form method="post" enctype="multipart/form-data" action="{{url_for('main.preview_job', service_id=current_service.id, template_id=template_id, upload_id=upload_id)}}" class='page-footer'>

View File

@@ -92,7 +92,7 @@
</table>
</div>
{% endif %}
<!-- <div class="bottom-gutter-3-2">
<!-- <div class="margin-bottom-3">
<p>This is a placeholder: This message will be delivered to <b>400 phone numbers</b> and will use a total of <b>800 message parts</b>, leaving Washington DSHS with <b>249,200 message parts remaining</b>.</p>
</div> -->
<form method="post" enctype="multipart/form-data" action="{{url_for('main.start_job', service_id=current_service.id, upload_id=upload_id)}}" class='page-footer'>

View File

@@ -49,7 +49,7 @@
{% block maincolumn_content %}
<h1 class="heading-large {% if current_user.has_access_to_live_and_trial_mode_services %}usa-sr-only{% endif %}">
<h1 class="font-heading-xl {% if current_user.has_access_to_live_and_trial_mode_services %}usa-sr-only{% endif %}">
Choose service
</h1>

View File

@@ -15,8 +15,8 @@
<div class="dashboard">
<div class="bottom-gutter js-stick-at-top-when-scrolling">
<h1 class="heading-large">
<div class="margin-bottom-3 js-stick-at-top-when-scrolling">
<h1 class="font-heading-xl">
{{ user_number }}
</h1>
</div>

View File

@@ -1,7 +1,7 @@
{% from "components/table.html" import list_table, field, right_aligned_field_heading, row_heading %}
<div class="table-overflow-x-auto">
<div class='dashboard-table ajax-block-container'>
<div class='dashboard-uploads-table ajax-block-container'>
{% call(item, row_number) list_table(
jobs,
caption="Recent files uploaded",
@@ -16,8 +16,8 @@
field_headings_visible=False
) %}
{% call row_heading() %}
<div class="file-list">
<a class="file-list-filename-large usa-link" href="{{ url_for('.view_job', service_id=current_service.id, job_id=item.id) }}">{{ item.original_file_name }}</a>
<div class="file-name-cell">
<a class="file-link usa-link" href="{{ url_for('.view_job', service_id=current_service.id, job_id=item.id) }}" title="{{ item.original_file_name }}">{{ item.original_file_name }}</a>
{% if item.scheduled %}
<span class="file-list-hint-large">
Sending {{
@@ -59,56 +59,29 @@
</a>
{% endif %}
{% else %}
<div class="grid-row">
<div class="grid-col-4">
<div class="status-display">
<span class="status-item">
{% if link %}
<a class="usa-link display-flex" href="{{ link }}">
<a class="usa-link" href="{{ link }}">
{% endif %}
<span class="big-number-smallest">
<span class="big-number-number">
{{ "{:,}".format(item.notifications_sending) }}
</span>
<span class="big-number-label">pending</span>
</span>
<strong>{{ "{:,}".format(item.notifications_sending) }}</strong> pending
{% if link %}
</a>
{% endif %}
</div>
<div class="grid-col-4">
<span class="big-number-smallest">
<span class="big-number-number">
{% if item.notifications_delivered is number %}
{{ "{:,}".format(item.notifications_delivered) }}
{% else %}
{{ item.notifications_delivered }}
{% endif %}
</span>
<span class="big-number-label">delivered</span>
</span>
</div>
<div class="grid-col-4">
{% if link %}
<a class="usa-link display-flex" href="{{ link }}">
{% endif %}
<span class="big-number-smallest">
<span class="big-number-number">
{% if item.notifications_failed is number %}
{% if currency %}
{{ "{}{:,.2f}".format(currency, item.notifications_failed) }}
{% else %}
{{ "{:,}".format(item.notifications_failed) }}
{% endif %}
{% else %}
{{ item.notifications_failed }}
{% endif %}
</span>
<span class="big-number-label">failed</span>
</span>
{% if link %}
</a>
{% endif %}
</div></div>
<span class="status-item">
<strong>{{ "{:,}".format(item.notifications_delivered) if item.notifications_delivered is number else item.notifications_delivered }}</strong> delivered
</span>
<span class="status-item">
{% if link %}
<a class="usa-link" href="{{ link }}">
{% endif %}
<strong>{{ "{:,}".format(item.notifications_failed) if item.notifications_failed is number else item.notifications_failed }}</strong> failed
{% if link %}
</a>
{% endif %}
</span>
</div>
{% endif %}
{% endcall %}

View File

@@ -12,7 +12,7 @@
{{ page_header("Templates used") }}
<div class="bottom-gutter-3-2">
<div class="margin-bottom-3">
{{ pill(
items=years,
current_value=selected_year,

View File

@@ -12,7 +12,7 @@
{% block maincolumn_content %}
{{ page_header('Messages sent') }}
<div class="bottom-gutter">
<div class="margin-bottom-3">
{{ pill(
items=years,
current_value=selected_year,

View File

@@ -19,12 +19,12 @@
('python', 'Python'),
('ruby', 'Ruby'),
] %}
<li><a class="usa-link" href="https://docs.notifications.service.gov.uk/{{ key }}.html" target="_blank" rel="noopener">{{ label }}</a></li>
<li><a class="usa-link" href="https://docs.notifications.example.gov/{{ key }}.html" target="_blank" rel="noopener">{{ label }}</a></li>
{% endfor %}
</ul>
<p>A developer should be able to set up the API client and start sending test messages in around 30 minutes. A full integration can take a few days, depending on the other systems youre using.</p>
<h2 class="font-body-lg" id="integrate-directly-with-the-api">Integrate directly with the API</h2>
<p>If you cannot use the client libraries, you can integrate directly with the API instead.</p>
<p>Read the <a class="usa-link" href="https://docs.notifications.service.gov.uk/rest-api.html" target="_blank" rel="noopener">REST API documentation</a> (this link opens in a new tab).</p>
<p>Read the <a class="usa-link" href="https://docs.notifications.example.gov/rest-api.html" target="_blank" rel="noopener">REST API documentation</a> (this link opens in a new tab).</p>
{% endblock %}

View File

@@ -18,30 +18,30 @@
<p class="usa-body"><a class="usa-link" href="{{ url_for('main.register') }}">Create an account</a> for free and try it yourself.</p>
{% endif %}
<h2 class="heading-medium" id="templates">Reusable message templates</h2>
<h2 class="font-heading-lg" id="templates">Reusable message templates</h2>
<p class="usa-body">To send a text with Notify, you need to create a reusable message template first.</p>
<p class="usa-body">Templates let you send the same thing to lots of people, as often as you need to, without writing a new message each time.</p>
<h2 class="heading-medium" id="organizing-content">Organizing your content</h2>
<h2 class="font-heading-lg" id="organizing-content">Organizing your content</h2>
<p class="usa-body">You can organize your content by grouping templates, and putting them into folders.</p>
<p class="usa-body">Set up folders within the Send message section of Notify, where you find templates. You can choose to create a Folder before or after a template is made. If you want to change a users ability to view or edit folders, you may control this through their individual team member permissions.</p>
<h2 class="heading-medium" id="personalised-messages">Personalized content</h2>
<h2 class="font-heading-lg" id="personalised-messages">Personalized content</h2>
<p class="usa-body">Notify makes it easy to send personalized messages from a single template.</p>
<p class="usa-body">See <a class="usa-link" href="{{ url_for('.how_to', _anchor='personalized-content') }}">how to personalize your content</a>.</p>
<h2 class="heading-medium" id="bulk-sending">Bulk sending</h2>
<h2 class="font-heading-lg" id="bulk-sending">Bulk sending</h2>
<p class="usa-body">To send a batch of messages at once, upload a list of contact details to Notify. You can also schedule the date and time you want them to be sent.</p>
<!-- <h2 class="heading-medium" id="api">API integration</h2>
<!-- <h2 class="font-heading-lg" id="api">API integration</h2>
<p class="usa-body">You can integrate the Notify API with your web application or back-office system to send messages automatically.</p>
<p class="usa-body">Read our <a class="usa-link" href="{{ url_for('.documentation') }}">API documentation</a> for more information.</p> -->
<h2 class="heading-medium" id="reporting">Reporting</h2>
<h2 class="font-heading-lg" id="reporting">Reporting</h2>
<p class="usa-body">Notifys real-time dashboard lets you see the number of messages sent. You can also check the current status of any message to see when it was delivered.</p>
<p class="usa-body">Read more about the <a class="usa-link" href="{{ url_for('main.message_status') }}">delivery status</a> of your messages.</p>
<h2 class="heading-medium" id="permissions">Permissions</h2>
<h2 class="font-heading-lg" id="permissions">Permissions</h2>
<p class="usa-body">Control which members of your team can see, create, edit, and send messages.</p>
<p class="usa-body">Notify lets you:</p>
<ul class="list list-bullet">
@@ -49,7 +49,7 @@
<li>choose who else can manage team members</li>
</ul>
<h2 class="heading-medium" id="performance">Performance</h2>
<h2 class="font-heading-lg" id="performance">Performance</h2>
<p class="usa-body">Notify commits to sending 95% of text messages within 10 seconds.</p>
<!-- <ul class="list list-bullet">
<li>sending 95% of text messages within 10 seconds</li>
@@ -59,17 +59,17 @@
<!-- <p class="usa-body">Visit our <a class="usa-link" href="{{ url_for('main.performance') }}">performance data</a> page to see how Notify is performing.</p> -->
<h2 class="heading-medium" id="security">Security</h2>
<h2 class="font-heading-lg" id="security">Security</h2>
<p class="usa-body">Notify protects and manages data to meet the needs of government services.</p>
<h3 class="heading-small">Hide sensitive information</h3>
<h3 class="font-heading-md">Hide sensitive information</h3>
<p class="usa-body">Notify lets you redact personal information from your messages after they have been sent. This means that only the recipient can see that information.</p>
<h3 class="heading-small">Two-factor authentication</h3>
<h3 class="font-heading-md">Two-factor authentication</h3>
<p class="usa-body">Notify uses two-factor authentication (2FA) to keep your account secure. When you sign in, well send a unique one-time code to your phone and ask you to enter it before we let you use your account.</p>
<p class="usa-body">Read more about <a class="usa-link" href="{{ url_for('main.security') }}">security</a>.
<!-- <h2 class="heading-medium" id="support">Support</h2>
<!-- <h2 class="font-heading-lg" id="support">Support</h2>
<p class="usa-body">Notify provides 24-hour online support. If you have an emergency outside office hours, well reply within 30 minutes.</p>
<p class="usa-body">Find out more about <a class="usa-link" href="{{ url_for('.support') }}">support</a>.</p> -->

View File

@@ -14,7 +14,7 @@
<p><a class="usa-link" href="{{ url_for('main.register') }}">Create an account</a> and try Notify for yourself.</p>
{% endif %}
<h2 class="heading heading-medium">Features</h2>
<h2 class="heading font-heading-lg">Features</h2>
<p>Notify makes it easy to:</p>
<ul class="list list-bullet">
<li>create reusable text message templates</li>
@@ -38,7 +38,7 @@
<li>Select <b class="bold">Change</b> or <b class="bold">Add text message sender</b>.</li>
</ol>
<h2 class="heading heading-medium">Pricing<h2>
<h2 class="heading font-heading-lg">Pricing</h2>
<p>Each service you add has an annual allowance of free text messages.</p>
<p><a class="usa-link" href="{{ url_for('.pricing', _anchor='text-messages') }}">See pricing</a> for more details.</p>

View File

@@ -6,13 +6,13 @@
{% endblock %}
{% block platform_admin_content %}
<div class="grid-row bottom-gutter">
<div class="grid-row margin-bottom-3">
<div class="grid-col-12">
<h1 class="font-body-2xl margin-bottom-3">
{{ user.name }}
</h1>
<p>{{ user.email_address }}</p>
<p class="{{ '' if user.mobile_number else 'hint' }}">{{ user.mobile_number or 'No mobile number'}}</p>
<p class="{{ '' if user.mobile_number else 'usa-hint' }}">{{ user.mobile_number or 'No mobile number'}}</p>
<h2 class="font-body-lg">Live services</h2>
<nav class="browse-list">
@@ -25,7 +25,7 @@
{% endfor %}
</ul>
{% else %}
<p class="hint">
<p class="usa-hint">
No live services
</p>
{% endif %}
@@ -41,7 +41,7 @@
{% endfor %}
</ul>
{% else %}
<p class="hint">
<p class="usa-hint">
No services in trial mode
</p>
{% endif %}
@@ -57,7 +57,7 @@
<h2 class="font-body-lg">Last login</h2>
{% if not user.logged_in_at %}
<p class="hint">This person has never logged in</p>
<p class="usa-hint">This person has never logged in</p>
{% else %}
<p>Last logged in
<time datetime="{{ user.logged_in_at }}">

View File

@@ -7,7 +7,7 @@
{% block content_column_content %}
<h1 class="heading-large">Edit and format messages</h1>
<h1 class="font-heading-xl">Edit and format messages</h1>
<p class="usa-body">This page explains how to:</p>
<ul class="list list-bullet">
@@ -17,7 +17,7 @@
<li><a class="usa-link" href="#optional-content">add optional content</a></li>
</ul>
<h2 class="heading-medium" id="formatting">Format your content</h2>
<h2 class="font-heading-lg" id="formatting">Format your content</h2>
<p class="usa-body">You can see a list of formatting instructions on the edit template page:</p>
@@ -36,7 +36,7 @@
<p class="usa-body">Notify does not allow bold, italics, subheadings, underlined text or different fonts. This is because they can make it harder for users to read what youve written.</p> -->
<h2 class="heading-medium" id="links">Add links</h2>
<h2 class="font-heading-lg" id="links">Add links</h2>
<p class="usa-body">When composing a text message, write URLs in full and Notify will convert them into links for you.</p>
@@ -50,7 +50,7 @@
<li>you can no longer control where the redirect goes</li>
</ul>
<h2 class="heading-medium" id="personalized-content">Personalize your content</h2>
<h2 class="font-heading-lg" id="personalized-content">Personalize your content</h2>
<p class="usa-body">To personalize the content of your messages, add a placeholder to the template.</p>
@@ -74,7 +74,7 @@
<p class="usa-body">If you upload a list, the column names need to match the placeholders in your template.</p>
<h2 class="heading-medium" id="optional-content">Add optional content</h2>
<h2 class="font-heading-lg" id="optional-content">Add optional content</h2>
<p class="usa-body">To add optional content to your messages:</p>

View File

@@ -44,21 +44,21 @@
<div class="user-list-item width-full">
<h2 class="user-list-item-heading font-body-lg margin-y-0" title="{{ user.email_address }}">
{%- if user.name -%}
<span class="heading-small live-search-relevant">{{ user.name }}</span>
<span class="font-heading-md live-search-relevant">{{ user.name }}</span>
{%- else -%}
<span class="heading-small live-search-relevant">{{ user.email_address }}</span>
<span class="font-heading-md live-search-relevant">{{ user.email_address }}</span>
{%- endif -%}
</h2>
<p class="margin-top-0">
{%- if user.status == 'pending' -%}
<span class="live-search-relevant">{{ user.email_address }}</span>
<span class="hint">(invited)</span>
<span class="usa-hint">(invited)</span>
{%- elif user.status == 'expired' -%}
<span class="live-search-relevant">{{ user.email_address }}</span>
<span class="hint">(expired invite)</span>
<span class="usa-hint">(expired invite)</span>
{%- elif user.id == current_user.id -%}
<span class="live-search-relevant">{{ user.email_address }}</span>
<span class="hint">(you)</span>
<span class="usa-hint">(you)</span>
{%- else -%}
<span class="live-search-relevant">{{ user.email_address }}</span>
{% endif %}

View File

@@ -21,7 +21,7 @@
<div class="grid-col-12">
{% call form_wrapper() %}
<p>New email address:</p>
<div class="panel panel-border-wide bottom-gutter">
<div class="usa-alert usa-alert--info margin-bottom-3">
<p>{{ new_email }}</p>
</div>
<p>We will send {{ user.name }} an email to tell them about the change.</p>

View File

@@ -20,7 +20,7 @@
<div class="grid-col-12">
{% call form_wrapper() %}
<p>New mobile number:</p>
<div class="panel panel-border-wide bottom-gutter">
<div class="usa-alert usa-alert--info margin-bottom-3">
<p>{{ new_mobile_number }}</p>
</div>
<p>We will send {{ user.name }} a text message to tell them about the change.</p>

View File

@@ -3,9 +3,238 @@
{{ form.permissions_field }}
{% if form.folder_permissions.all_template_folders %}
{{ form.folder_permissions }}
<div class="folder-permissions-section margin-top-5">
<fieldset class="usa-fieldset">
<legend class="usa-legend">
<h3 class="font-body-lg margin-bottom-3">Folders this team member can see</h3>
</legend>
<div class="display-flex flex-justify flex-align-center margin-bottom-3">
<span class="text-base-dark" aria-live="polite" aria-atomic="true">
<span id="folder-counter">0</span> of <span id="folder-total">0</span> selected
</span>
<button type="button" class="usa-button usa-button--outline" id="select-all-folders">
Select all
</button>
</div>
<div class="border-1px border-base-lighter radius-md padding-4 folder-permissions-container selection-wrapper">
<div id="custom-folder-permissions">
<ul class="usa-list usa-list--unstyled" role="list" aria-label="Folder permissions">
{% set folder_dict = {} %}
{% for folder in form.folder_permissions.all_template_folders %}
{% set _ = folder_dict.update({folder.id: folder}) %}
{% endfor %}
{% macro render_folder(folder_id, folder_name, level=0, is_checked=False, parent_id=None) %}
<li class="folder-permission-item {% if level > 0 %}margin-left-{{ level * 5 }}{% endif %} {% if level > 0 %}text-base-dark{% endif %}"
{% if parent_id %}data-parent-id="{{ parent_id }}"{% endif %}
data-folder-id="{{ folder_id }}">
<div class="usa-checkbox {% if level > 0 %}padding-left-2{% endif %}">
<input
class="usa-checkbox__input js-folder-checkbox"
id="folder_{{ folder_id|replace('-', '_')|default('root', true) }}"
name="folder_permissions"
type="checkbox"
value="{{ folder_id }}"
{% if is_checked %}checked{% endif %}
data-level="{{ level }}"
{% if parent_id %}data-parent-id="{{ parent_id }}"{% endif %}
>
<label class="usa-checkbox__label {% if level == 0 %}text-bold{% endif %} {% if level > 1 %}font-body-xs{% endif %}" for="folder_{{ folder_id|replace('-', '_')|default('root', true) }}">
{{ folder_name }}
</label>
</div>
</li>
{% endmacro %}
{% for folder in form.folder_permissions.all_template_folders %}
{% if folder.parent_id is none %}
{{ render_folder(folder.id, folder.name, 0, folder.id in (form.folder_permissions.data or []), None) }}
{% for child in form.folder_permissions.all_template_folders %}
{% if child.parent_id == folder.id %}
{{ render_folder(child.id, child.name, 1, child.id in (form.folder_permissions.data or []), folder.id) }}
{% for grandchild in form.folder_permissions.all_template_folders %}
{% if grandchild.parent_id == child.id %}
{{ render_folder(grandchild.id, grandchild.name, 2, grandchild.id in (form.folder_permissions.data or []), child.id) }}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
</ul>
</div>
</div>
</fieldset>
</div>
<style nonce="{{ csp_nonce() }}">
.folder-permissions-container {
max-height: 400px;
overflow-y: auto;
}
.folder-permission-item {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
.folder-permission-item:hover {
background-color: var(--usa-base-lightest);
border-radius: 0.25rem;
}
#custom-folder-permissions .usa-checkbox {
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
#custom-folder-permissions .usa-checkbox__label {
margin-top: 0;
}
</style>
<script nonce="{{ csp_nonce() }}">
(function() {
'use strict';
function initFolderPermissions() {
const selectAllBtn = document.getElementById('select-all-folders');
const folderContainer = document.getElementById('custom-folder-permissions');
const folderCounter = document.getElementById('folder-counter');
const folderTotal = document.getElementById('folder-total');
if (!selectAllBtn || !folderContainer || !folderCounter || !folderTotal) {
console.error('Folder permissions: Required elements not found');
return;
}
const folderCheckboxes = folderContainer.querySelectorAll('input.js-folder-checkbox');
if (!folderCheckboxes.length) {
console.error('Folder permissions: No checkboxes found');
return;
}
folderTotal.textContent = folderCheckboxes.length;
function updateCounter() {
let checkedCount = 0;
folderCheckboxes.forEach(function(checkbox) {
if (checkbox.checked) {
checkedCount++;
}
});
folderCounter.textContent = checkedCount;
if (checkedCount === folderCheckboxes.length && checkedCount > 0) {
selectAllBtn.textContent = 'Deselect all';
} else {
selectAllBtn.textContent = 'Select all';
}
}
function toggleSelectAll(event) {
event.preventDefault();
let checkedCount = 0;
folderCheckboxes.forEach(function(checkbox) {
if (checkbox.checked) {
checkedCount++;
}
});
const shouldCheck = checkedCount !== folderCheckboxes.length;
folderCheckboxes.forEach(function(checkbox) {
checkbox.checked = shouldCheck;
});
updateCounter();
}
function handleParentSelection(parentCheckbox, isUserAction) {
const parentId = parentCheckbox.value;
if (!parentId) return;
const children = folderContainer.querySelectorAll(`[data-parent-id="${parentId}"] input.js-folder-checkbox`);
children.forEach(function(childCheckbox) {
if (childCheckbox.checked !== parentCheckbox.checked) {
childCheckbox.checked = parentCheckbox.checked;
handleParentSelection(childCheckbox, false);
}
});
if (isUserAction) {
updateCounter();
}
}
function updateParentState(childCheckbox) {
const parentId = childCheckbox.getAttribute('data-parent-id');
if (!parentId) return;
const parentCheckbox = folderContainer.querySelector(`input.js-folder-checkbox[value="${parentId}"]`);
if (!parentCheckbox) return;
const siblings = folderContainer.querySelectorAll(`[data-parent-id="${parentId}"] input.js-folder-checkbox`);
let allChecked = true;
let anyChecked = false;
siblings.forEach(function(sibling) {
if (sibling.checked) {
anyChecked = true;
} else {
allChecked = false;
}
});
if (allChecked) {
parentCheckbox.checked = true;
parentCheckbox.indeterminate = false;
} else if (anyChecked) {
parentCheckbox.checked = false;
parentCheckbox.indeterminate = true;
} else {
parentCheckbox.checked = false;
parentCheckbox.indeterminate = false;
}
updateParentState(parentCheckbox);
}
selectAllBtn.addEventListener('click', toggleSelectAll);
folderCheckboxes.forEach(function(checkbox) {
checkbox.addEventListener('change', function(event) {
if (event.isTrusted) {
handleParentSelection(checkbox, true);
updateParentState(checkbox);
updateCounter();
}
});
});
updateCounter();
folderCheckboxes.forEach(function(checkbox) {
if (checkbox.checked) {
updateParentState(checkbox);
}
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initFolderPermissions);
} else {
setTimeout(initFolderPermissions, 100);
}
})();
</script>
{% elif user and user.platform_admin %}
<p class="bottom-gutter usa-body">
<p class="margin-bottom-3 usa-body">
Platform admin users can access all template folders.
</p>
{% endif %}

View File

@@ -19,8 +19,8 @@
<!-- <p>If youre using the Notify API, read our <a class="usa-link" href="{{ url_for('.documentation') }}">documentation</a> for a list of API statuses.<p>
<h2 id="email-statuses" class="heading-medium">Emails</h2>
<div class="bottom-gutter-3-2">
<h2 id="email-statuses" class="font-heading-lg">Emails</h2>
<div class="margin-bottom-3">
{% call mapping_table(
caption='Message statuses emails',
field_headings=['Status', 'Description'],
@@ -31,7 +31,7 @@
('Sending', 'Notify has sent the message to the provider. The provider will try to deliver the message to the recipient for up to 72 hours. Notify is waiting for delivery information.'),
('Delivered', 'The message was successfully delivered. Notify cannot tell you if a user has opened or read a message.'),
('Email address does not exist', 'The provider could not deliver the message because the email address was wrong. You should remove these email addresses from your database.'),
('Inbox not accepting messages right now', 'The provider could not deliver the message. This can happen when the recipients inbox is full or their anti-spam filter rejects your email. <a class="usa-link" href="https://www.gov.uk/service-manual/design/sending-emails-and-text-messages#protect-your-users-from-spam-and-phishing">Check your content does not look like spam</a> before you try to send the message again.' | safe),
('Inbox not accepting messages right now', 'The provider could not deliver the message. This can happen when the recipient\'s inbox is full or their anti-spam filter rejects your email. Check your content does not look like spam before you try to send the message again.'),
('Technical failure', 'Your message was not sent because there was a problem between Notify and the provider. Youll have to try sending your messages again.'),
] %}
{% call row() %}
@@ -42,13 +42,13 @@
{% endcall %}
</div>
<h3 id="spam" class="heading-small">Spam</h3>
<h3 id="spam" class="font-heading-md">Spam</h3>
<p>If an email is marked as spam, Notify receives a complaint from the email provider. Well contact you if we receive a complaint about any of your emails. When this happens you should remove the recipients email address from your list.</p>
<h3 id="open-rates" class="heading-small">Open rates and click-throughs</h3>
<h3 id="open-rates" class="font-heading-md">Open rates and click-throughs</h3>
<p>Notify cannot tell you if your users open an email or click on the links in an email. We do not track open rates and click-throughs because there are privacy issues. Tracking emails without asking permission from users could breach General Data Protection Regulations (GDPR).</p> -->
<h2 id="text-message-statuses" class="heading-medium">Text messages</h2>
<h2 id="text-message-statuses" class="font-heading-lg">Text messages</h2>
<div class="margin-bottom-8 table-overflow-x-auto">
{% call mapping_table(
caption='Message statuses text messages',
@@ -60,8 +60,7 @@
('Scheduled', 'The total number of messages that have been scheduled to be sent at some future time.'),
('Canceled', 'Messages that were created and scheduled, but canceled prior to Sending.'),
('Total', 'The total number of messages that have been sent during the specified time.'),
('Pending', 'Notify has sent the message to the provider. The provider will try to deliver the message to the recipient for up to 72
hours. “Pending” indicates that Notify is waiting for delivery information.'),
('Pending', 'Notify has sent the message to the provider. The provider will try to deliver the message to the recipient for up to 72 hours. "Pending" indicates that Notify is waiting for delivery information.'),
('Delivered', 'The message was successfully delivered. Notify cannot tell you if a user has opened or read a message.'),
('Failed', 'The message could not be delivered.'),
('Process error / Delivery not attempted', 'If you receive a large number of process errors, please contact the Notify team.'),
@@ -73,14 +72,14 @@
{% endfor %}
{% endcall %}
</div>
<h2 class="heading-medium">About carrier statuses</h2>
<h2 class="font-heading-lg">About carrier statuses</h2>
<p>Sometimes Notify receives more detailed information from the carriers on the status of messages, and these can be found
in the downloadable reports. Not all carriers provide the same level of detail regarding delivery and some delivery
statutes have a slight variation in word choice. Notify includes this information in the reports to provide you as much
detail as possible. Remember, for security purposes, detailed information is only available for seven days after a
message has been sent.</p>
<h2 class="heading-medium">Opting out</h2>
<h2 class="font-heading-lg">Opting out</h2>
<p>A text recipient can opt out of receiving text messages from your phone number at any time by responding “STOP” or
“QUIT” or <a class="usa-link" href="https://docs.aws.amazon.com/pinpoint/latest/userguide/channels-sms-limitations-opt-out.html#settings-sms-self-opt-out-terms">one of several other keywords</a>. If they opt out,</p>
<ul>

View File

@@ -64,20 +64,20 @@
{% if current_user.has_permissions(ServicePermission.VIEW_ACTIVITY) %}
<p class="font-body-sm">
<a href="{{ download_link_seven_day }}" download="download" class="usa-link">Download all data last 7 days (<abbr title="Comma separated values">CSV</abbr>)</a>
<a href="{{ download_link_seven_day }}" download="download" class="usa-button usa-button--outline">Download all data last 7 days (<abbr title="Comma separated values">CSV</abbr>)</a>
&emsp;
Data available for {{ partials.service_data_retention_days }} days
</p>
<p class="font-body-sm">
<a href="{{ download_link_five_day }}" download="download" class="usa-link">Download all data last 5 days (<abbr title="Comma separated values">CSV</abbr>)</a>
<a href="{{ download_link_five_day }}" download="download" class="usa-button usa-button--outline">Download all data last 5 days (<abbr title="Comma separated values">CSV</abbr>)</a>
&emsp;
</p>
<p class="font-body-sm">
<a href="{{ download_link_three_day }}" download="download" class="usa-link">Download all data last 3 days (<abbr title="Comma separated values">CSV</abbr>)</a>
<a href="{{ download_link_three_day }}" download="download" class="usa-button usa-button--outline">Download all data last 3 days (<abbr title="Comma separated values">CSV</abbr>)</a>
&emsp;
</p>
<p class="font-body-sm">
<a href="{{ download_link_today }}" download="download" class="usa-link">Download all data today (<abbr title="Comma separated values">CSV</abbr>)</a>
<a href="{{ download_link_today }}" download="download" class="usa-button usa-button--outline">Download all data today (<abbr title="Comma separated values">CSV</abbr>)</a>
&emsp;
</p>
{% endif %}

View File

@@ -14,7 +14,7 @@
{% block maincolumn_content %}
{% if error == 'not-allowed-to-send-to' %}
<div class="bottom-gutter">
<div class="margin-bottom-3">
{% call banner_wrapper(type='dangerous') %}
{% with
count_of_recipients=1,
@@ -27,14 +27,14 @@
{% endcall %}
</div>
{% elif error == 'too-many-messages' %}
<div class="bottom-gutter">
<div class="margin-bottom-3">
{% call banner_wrapper(type='dangerous') %}
{% include "partials/check/too-many-messages.html" %}
{% endcall %}
</div>
{% elif error == 'message-too-long' %}
{# the only row_errors we can get when sending one off messages is that the message is too long #}
<div class="bottom-gutter">
<div class="margin-bottom-3">
{% call banner_wrapper(type='dangerous') %}
{% include "partials/check/message-too-long.html" %}
{% endcall %}

View File

@@ -24,7 +24,7 @@
{% block maincolumn_content %}
{% if error == 'not-allowed-to-send-to' %}
<div class="bottom-gutter">
<div class="margin-bottom-3">
{% call banner_wrapper(type='dangerous') %}
{% with
count_of_recipients=1,
@@ -37,13 +37,13 @@
{% endcall %}
</div>
{% elif error == 'too-many-messages' %}
<div class="bottom-gutter">
<div class="margin-bottom-3">
{% call banner_wrapper(type='dangerous') %}
{% include "partials/check/too-many-messages.html" %}
{% endcall %}
</div>
{% elif error == 'message-too-long' %}
<div class="bottom-gutter">
<div class="margin-bottom-3">
{% call banner_wrapper(type='dangerous') %}
{% include "partials/check/message-too-long.html" %}
{% endcall %}

View File

@@ -18,7 +18,7 @@
<li class="browse-list-item">
<a href="{{ url_for('main.organization_dashboard', org_id=org.id) }}" class="usa-link">{{ org.name }}</a>
{% if not org.active %}
<span class="table-field-status-default heading-medium">- archived</span>
<span class="table-field-status-default font-heading-lg">- archived</span>
{% endif %}
<p class="browse-list-hint">
{{ org.count_of_live_services }}

View File

@@ -12,13 +12,13 @@
{{ page_header('Usage', size='medium') }}
<div class="bottom-gutter">
<div class="margin-bottom-3">
{{ pill(years, selected_year, big_number_args={'smallest': True}) }}
</div>
<div class="grid-row bottom-gutter">
<div class="grid-row margin-bottom-3">
<div class="grid-col-6">
<h2 class="heading-small">Emails</h2>
<h2 class="font-heading-md">Emails</h2>
<div class="keyline-block">
{{ big_number(
total_emails_sent,
@@ -28,7 +28,7 @@
</div>
</div>
<div class="grid-col-6">
<h2 class="heading-small">Text messages</h2>
<h2 class="font-heading-md">Text messages</h2>
<div class="keyline-block">
{{ big_number(
total_sms_cost,
@@ -51,7 +51,7 @@
</div>
{% endif %}
<h2 class="heading-small {% if search_form %}visually-hidden{% endif %}">By service</h2>
<h2 class="font-heading-md {% if search_form %}visually-hidden{% endif %}">By service</h2>
{% for service in services %}
<div class="keyline-block organization-service">

View File

@@ -26,7 +26,7 @@
form.domains,
item_name='domain',
autocomplete=False,
hint='For example cabinet-office.gov.uk'
hint='For example example.gov'
) }}
{{ page_footer('Save') }}
{% endcall %}

View File

@@ -7,7 +7,7 @@
{% block maincolumn_content %}
<h1 class="font-body-2xl">Settings</h1>
<div class="bottom-gutter-3-2 settings-table body-copy-table">
<div class="margin-bottom-3 settings-table body-copy-table">
{% call mapping_table(
caption='General',
field_headings=['Label', 'Value', 'Action'],

View File

@@ -36,9 +36,9 @@
<div class="grid-col-9">
<h2 class="user-list-item-heading">
{%- if user.name -%}
<span class="heading-small">{{ user.name }}</span>&ensp;
<span class="font-heading-md">{{ user.name }}</span>&ensp;
{%- endif -%}
<span class="hint">
<span class="usa-hint">
{%- if user.status == 'pending' -%}
{{ user.email_address }} (invited)
{%- elif user.status == 'cancelled' -%}

View File

@@ -24,7 +24,7 @@
error_message_with_html=True
) }}
<div class="bottom-gutter">
<div class="margin-bottom-3">
<p class="form-label">
{{ current_org.name }} team members can:
</p>

View File

@@ -109,7 +109,7 @@
<h2 class="font-body-lg">
Organizations using Notify
</h2>
<div class="grid-row bottom-gutter">
<div class="grid-row margin-bottom-3">
<div class="grid-col-6">
<span class="usa-sr-only">There are</span>
<div class="product-page-big-number">{{ count_of_live_services_and_organizations.organizations|format_thousands }}</div>

View File

@@ -1,4 +1,4 @@
<div class="grid-row bottom-gutter">
<div class="grid-row margin-bottom-3">
<div class="grid-col-6">
<span class="big-number-with-status">
{% if link %}

View File

@@ -21,7 +21,7 @@
<h2 class="font-body-lg">
Data included in the report
</h2>
<div class="bottom-gutter-3-2">
<div class="margin-bottom-3">
{% call mapping_table(
caption='Descriptions of daily SMS provider volumes data',
field_headings=['Name', 'Description'],

View File

@@ -21,7 +21,7 @@
<h2 class="font-body-lg">
Data included in the report
</h2>
<div class="bottom-gutter-3-2">
<div class="margin-bottom-3">
{% call mapping_table(
caption='Descriptions of daily volumes data',
field_headings=['Name', 'Description'],

View File

@@ -21,7 +21,7 @@
<h2 class="font-body-lg">
Data included in the report
</h2>
<div class="bottom-gutter-3-2">
<div class="margin-bottom-3">
{% call mapping_table(
caption='Descriptions of billing report data',
field_headings=['Name', 'Description'],
@@ -30,7 +30,7 @@
) %}
{% for column_heading, description in [
('sms cost', 'The total cost of text messages sent after a service has used its free allowance.'),
('sms chargeable units', 'The number of fragments sent after a service has used its free allowance. This number takes into account the cost multiplier for <a class="usa-link" href="https://www.notifications.service.gov.uk/pricing#international-numbers">sending international text messages</a>.' | safe),
('sms chargeable units', 'The number of fragments sent after a service has used its free allowance. This number takes into account the cost multiplier for sending international text messages.' | safe),
('purchase order number, contact names, contact email addresses and billing reference', 'We add this data manually based on the information we get from services. You can help by adding it to the service settings page.'),
] %}
{% call row() %}

View File

@@ -21,7 +21,7 @@
<h2 class="font-body-lg">
Data included in the report
</h2>
<div class="bottom-gutter-3-2">
<div class="margin-bottom-3">
{% call mapping_table(
caption='Descriptions of billing report data',
field_headings=['Name', 'Description'],
@@ -30,7 +30,7 @@
) %}
{% for column_heading, description in [
('sms cost', 'The total cost of text messages sent after a service has used its free allowance.'),
('sms chargeable units', 'The number of fragments sent after a service has used its free allowance. This number takes into account the cost multiplier for <a class="usa-link" href="https://www.notifications.service.gov.uk/pricing#international-numbers">sending international text messages</a>.' | safe),
('sms chargeable units', 'The number of fragments sent after a service has used its free allowance. This number takes into account the cost multiplier for sending international text messages.' | safe),
('purchase order number, contact names, contact email addresses and billing reference', 'We add this data manually based on the information we get from services. You can help by adding it to the service settings page.'),
] %}
{% call row() %}

View File

@@ -29,7 +29,7 @@
"open": form.errors | convert_to_boolean
}) }}
<div class="grid-row bottom-gutter">
<div class="grid-row margin-bottom-3">
{% for noti_type in global_stats %}
<div class="grid-col-6">
<span class="big-number-dark">
@@ -54,7 +54,7 @@
{% endfor %}
</div>
<div class="grid-row bottom-gutter">
<div class="grid-row margin-bottom-3">
{% for noti_type in global_stats %}
<div class="grid-col-6">
<div class="bordered-text-box">

View File

@@ -26,7 +26,7 @@
{% call field(border=False, colspan=3) %}
<a href="{{ url_for('main.service_dashboard', service_id=service['id']) }}" class="file-list-filename-large usa-link">{{ service['name'] }}</a>
{% if not service['active'] %}
<span class="heading-medium hint">&ensp;Archived</span>
<span class="font-heading-lg usa-hint">&ensp;Archived</span>
{% endif %}
{% if service['name'] == 'Test service' %}
<a class="usa-link" href="{{ url_for('main.load_test') }}">Load Test</a>

View File

@@ -11,7 +11,7 @@
</h1>
<p class="usa-body">
<a class="usa-link" href="{{ url_for('main.platform_admin') }}">Load summary</a>
<a class="usa-button usa-button--outline" href="{{ url_for('main.platform_admin') }}">Load summary</a>
</p>
{% endblock %}

View File

@@ -21,7 +21,7 @@
<h2 class="font-body-lg">
Data included in the report
</h2>
<div class="bottom-gutter-3-2">
<div class="margin-bottom-3">
{% call mapping_table(
caption='Descriptions of volumes by service data',
field_headings=['Name', 'Description'],

View File

@@ -1,26 +0,0 @@
{% extends "base.html" %}
{% from "components/page-header.html" import page_header %}
{% block per_page_title %}
Billing details
{% endblock %}
{% block content_column_content %}
{{ page_header('Billing details') }}
<p>
<a class="usa-link" href="{{ url_for('.sign_in', next=url_for('.billing_details')) }}">Sign in</a> to see our:
</p>
<ul class="usa-list usa-list--bullet">
<li>supplier details</li>
<li>bank details</li>
<li>invoice address</li>
</ul>
<p>
You can use this information to add the Cabinet Office as a supplier. Your organization may need to do this before you can raise a purchase order.
</p>
{% endblock %}

View File

@@ -1,138 +0,0 @@
{% extends "base.html" %}
{% from "components/page-header.html" import page_header %}
{% from "components/copy-to-clipboard.html" import copy_to_clipboard %}
{% block per_page_title %}
Billing details
{% endblock %}
{% block content_column_content %}
{{ page_header('Billing details') }}
<p>
You can use the information on this page to add the Cabinet Office as a supplier. Your organization may need to do this before you can raise a purchase order (PO).
</p>
<p>
<a class="usa-link" href="{{ url_for('main.support') }}">Contact us</a> if you need any other details.
</p>
<h2 class="heading-medium" id="supplier-details">
Supplier details
</h2>
<p>
Cabinet Office
</p>
<p>
The White Chapel Building <br>
10 Whitechapel High Street <br>
London <br>
E1 8QS
</p>
<h3 class="font-body-lg" id="email-addresses">
Email addresses
</h3>
<ul class="usa-list usa-list--bullet">
{% for email in billing_details['notify_billing_email_addresses'] %}
<li>
{{ email }}
</li>
{% endfor %}
</ul>
<h3 class="font-body-lg" id="vat-number">
<abbr title="Value Added Tax">VAT</abbr> number
</h3>
<div>
{{ copy_to_clipboard(
'GB 88 88 010 80',
thing='<abbr title="Value Added Tax">VAT</abbr> number',
) }}
</div>
<h2 class="heading-medium" id="bank-details">
Bank details
</h2>
<p>
National Westminster Bank PLC (part of RBS group) <br>
Government Banking Services Branch <br>
2nd Floor <br>
280 Bishopsgate <br>
London <br>
EC2M 4RB
</p>
<h3 class="font-body-lg" id="account-name">
Account name
</h3>
<p>
Cabinet Office
</p>
<h3 class="font-body-lg" id="account-number">
Account number
</h3>
<div>
{{ copy_to_clipboard(
billing_details['account_number'],
thing='account number',
) }}
</div>
<h3 class="font-body-lg" id="sort-code">
Sort code
</h3>
<div>
{{ copy_to_clipboard(
billing_details['sort_code'],
thing='sort code',
) }}
</div>
<h3 class="font-body-lg" id="iban">
<abbr title="International Bank Account Number">IBAN</abbr>
</h3>
<div>
{{ copy_to_clipboard(
billing_details['IBAN'],
thing='IBAN',
) }}
</div>
<h3 class="font-body-lg" id="swift-code">
Swift code
</h3>
<div>
{{ copy_to_clipboard(
billing_details['swift'],
thing='Swift code',
) }}
</div>
<h2 class="heading-medium" id="invoice-address">
Invoice address
</h2>
<p>
SSCL Accounts Receivable <br>
PO Box 221 <br>
Thornton-Cleveleys <br>
Blackpool <br>
Lancashire <br>
FY1 9JN
</p>
{% endblock %}

View File

@@ -58,7 +58,7 @@
</p>
<p>
Your organization may need to <a class="usa-link" href="{{ url_for('main.billing_details') }}">add the Cabinet Office as a supplier</a> before you can raise a <abbr title="purchase order">PO</abbr>.
Your organization may need to <a class="usa-link" href="#">add the Cabinet Office as a supplier</a> before you can raise a <abbr title="purchase order">PO</abbr>.
</p> -->
{% endblock %}

View File

@@ -102,7 +102,7 @@
<p>
Essential cookies keep your information secure while you use Notify. We do not need to ask permission to use them.
</p>
<table>
<table class="usa-table usa-table--borderless">
<caption class="usa-sr-only">Essential cookies</caption>
<thead>
<tr>
@@ -152,7 +152,7 @@
<li>the pages you visit on Notify and how long you spend on them</li>
<li>any errors you see while using Notify</li>
</ul>
<table>
<table class="usa-table usa-table--borderless">
<caption class="usa-sr-only">Google Analytics cookies</caption>
<thead>
<tr>

View File

@@ -55,10 +55,10 @@
{% if skip_link or link_to_upload %}
<div class="grid-col-12 margin-top-1">
{% if link_to_upload %}
<a class="usa-link margin-right-2" href="{{ url_for('.send_messages', service_id=current_service.id, template_id=template.id) }}">Upload a list of {{ 999|recipient_count_label(template.template_type) }}</a>
<a class="usa-button usa-button--outline margin-right-2" href="{{ url_for('.send_messages', service_id=current_service.id, template_id=template.id) }}">Upload a list of {{ 999|recipient_count_label(template.template_type) }}</a>
{% endif %}
{% if skip_link %}
<a href="{{ skip_link[1] }}" class="usa-link">{{ skip_link[0] }}</a>
<a href="{{ skip_link[1] }}" class="usa-button usa-button--outline">{{ skip_link[0] }}</a>
{% endif %}
</div>
{% endif %}

View File

@@ -14,7 +14,7 @@
{% block backLink %}
{{ usaBackLink({
"href": url_for('main.send_one_off_step', service_id=current_service.id, template_id=template.id, step_index=0),
"html": "Back to select recipients"
"html": "Back to message personalization"
}) }}
{% endblock %}
@@ -63,7 +63,7 @@
{{ page_header('Upload your bulk-sending spreadsheet')}}
<p class="font-sans-lg text-base">Organize phone numbers and information in a single spreadsheet and upload when you have multiple messages to send. Column headers in the spreadsheet will place the data in the right spots within the template that's selected.</p>
<div class="page-footer bottom-gutter margin-top-3">
<div class="page-footer margin-bottom-3 margin-top-3">
{{file_upload(
form.file,
allowed_file_extensions=allowed_file_extensions,
@@ -88,7 +88,7 @@
{% endfor %}
{% endcall %}
</div>
<p class="hint">
<p class="usa-hint">
Each template saved in Notify is given an example <abbr title="Comma Separated Values">CSV</abbr> formatted spreadsheet like this. It's the most reliable file format for uploading your contact list. Use this example to populate your template with the right data items. Start by downloading this example for your message template. Then save it as a <abbr title="Comma Separated Values">CSV</abbr> file for bulk messaging.
</p>
<p class="table-show-more-link">

View File

@@ -16,7 +16,7 @@
<h1 class="font-body-lg">Settings</h1>
<div class="bottom-gutter-3-2 settings-table body-copy-table table-overflow-x-auto">
<div class="margin-bottom-3 settings-table body-copy-table table-overflow-x-auto">
{% call mapping_table(
caption='General',
@@ -57,7 +57,7 @@
{% call field(status='default' if current_service.default_sms_sender == "None" else '') %}
{{ current_service.default_sms_sender | nl2br if current_service.default_sms_sender else 'None'}}
{% if current_service.count_sms_senders > 1 %}
<div class="hint">
<div class="usa-hint">
{{ '…and %d more' | format(current_service.count_sms_senders - 1) }}
</div>
{% endif %}
@@ -138,7 +138,7 @@
{% call field(status='default' if current_service.count_email_reply_to_addresses == 0 else '') %}
{{ current_service.default_email_reply_to_address or 'Not set' }}
{% if current_service.count_email_reply_to_addresses > 1 %}
<div class="hint">
<div class="usa-hint">
{{ '…and %d more' | format(current_service.count_email_reply_to_addresses - 1) }}
</div>
{% endif %}
@@ -187,7 +187,7 @@
</p>
{% else %}
<h2 class="heading-medium top-gutter-0">Your service is live</h2>
<h2 class="font-heading-lg top-gutter-0">Your service is live</h2>
<p>
You can send up to
@@ -218,7 +218,6 @@
{{ text_field('Live')}}
{% if current_service.trial_mode and not current_service.organization_id %}
{{ text_field('No (organization must be set first)') }}
{{ text_field('') }}
{% else %}
{{ boolean_field(not current_service.trial_mode) }}
{{ edit_field('Change', url_for('.service_switch_live', service_id=current_service.id), suffix='service status') }}
@@ -253,7 +252,7 @@
<span class="table-field-status-default">Not set</span>
{% endif %}
{% if current_service.organization_type %}
<div class="hint">
<div class="usa-hint">
{{ current_service.organization_type_label }}
</div>
{% endif %}
@@ -327,13 +326,13 @@
</span>
{% if current_user.platform_admin %}
<span class="page-footer-link">
<a href="{{ url_for('.suspend_service', service_id=current_service.id) }}" class="usa-link usa-link--destructive page-footer-link">
<a href="{{ url_for('.suspend_service', service_id=current_service.id) }}" class="usa-button usa-button--outline">
Suspend service
</a>
</span>
<span class="page-footer-link">
<a href="{{ url_for('.history', service_id=current_service.id) }}" class="usa-link page-footer-link">
<a href="{{ url_for('.history', service_id=current_service.id) }}" class="usa-link">
Service history
</a>
</span>
@@ -342,7 +341,7 @@
{% endif %}
{% if (not current_service.active) and current_user.platform_admin %}
<p>
<div class="hint ">
<div class="usa-hint ">
Service suspended
</div>
@@ -353,7 +352,7 @@
</span>
<span class="page-footer-link">
<a href="{{ url_for('.history', service_id=current_service.id) }}" class="usa-link page-footer-link">
<a href="{{ url_for('.history', service_id=current_service.id) }}" class="usa-link">
Service history
</a>
</span>

View File

@@ -8,7 +8,7 @@
{% block maincolumn_content %}
<div class="grid-row bottom-gutter">
<div class="grid-row margin-bottom-3">
<div class="grid-col-8">
<h1 class="font-body-2xl margin-bottom-3">
Data retention
@@ -23,7 +23,7 @@
}) }}
</div>
</div>
<div class="grid-row bottom-gutter">
<div class="grid-row margin-bottom-3">
<div class="grid-col-12">
By default data is kept for 7 days
</div>
@@ -31,7 +31,7 @@
{% if not current_service.data_retention %}
<div class="user-list">
<div class="user-list-item">
<p class="usa-body user-list-item-blank hint">You have not added any data retention</p>
<p class="usa-body user-list-item-blank usa-hint">You have not added any data retention</p>
</div>
</div>
{% else %}

View File

@@ -25,7 +25,7 @@
}) }}
</div>
{% elif verification_status == "failure" %}
<div class="bottom-gutter">
<div class="margin-bottom-3">
{% call banner_wrapper(type='dangerous') %}
<h2 class='banner-title' data-module="track-error" data-error-type="reply-to-email-not-working" data-error-label="{{ upload_id }}">
Theres a problem with your reply-to address

View File

@@ -20,7 +20,7 @@
<div class="user-list">
{% if not current_service.email_reply_to_addresses %}
<div class="user-list-item">
<p class="usa-body user-list-item-blank hint">You have not added any reply-to email addresses yet</p>
<p class="usa-body user-list-item-blank usa-hint">You have not added any reply-to email addresses yet</p>
</div>
{% endif %}
{% for item in current_service.email_reply_to_addresses %}
@@ -28,7 +28,7 @@
<div class="grid-row">
<div class="grid-col-9">
<h2 class="user-list-item-heading">
<span class="heading-small">{{ item.email_address }}</span>&ensp;<span class="hint">
<span class="font-heading-md">{{ item.email_address }}</span>&ensp;<span class="usa-hint">
{%- if item.is_default -%}
(default)
{% endif %}

View File

@@ -32,7 +32,7 @@
</div>
{{ sticky_page_footer('Save') }}
{% else %}
<p class="hint"> No organizations </p>
<p class="usa-hint"> No organizations </p>
{% endif %}
{% endcall %}
{% endblock %}

View File

@@ -1,4 +1,5 @@
{% extends "withnav_template.html" %}
{% from "components/page-header.html" import page_header %}
{% from "components/page-footer.html" import page_footer %}
{% from "components/form.html" import form_wrapper %}
{% from "components/components/back-link/macro.njk" import usaBackLink %}
@@ -13,17 +14,12 @@
{% block maincolumn_content %}
{{ page_header(title) }}
<div class="grid-row">
<div class="grid-col-10">
{% call form_wrapper(data_force_focus=True) %}
{{ form.enabled(param_extensions={
"fieldset": {
"legend": {
"isPageHeading": True,
"classes": "usa-legend usa-legend--large"
}
}
}) }}
{{ form.enabled() }}
{{ page_footer('Save') }}
{% endcall %}
</div>

View File

@@ -21,8 +21,8 @@
{% call form_wrapper(data_force_focus=True) %}
{% if inbound_number %}
<p>
<span class="bottom-gutter-1-3"> {{ sms_sender.sms_sender }} </span>
<span class="hint"> This phone number receives replies and cannot be changed </span>
<span class="margin-bottom-1"> {{ sms_sender.sms_sender }} </span>
<span class="usa-hint"> This phone number receives replies and cannot be changed </span>
</p>
{% else %}
{{ form.sms_sender(param_extensions={

View File

@@ -20,7 +20,7 @@
<div class="user-list">
{% if not current_service.sms_senders %}
<div class="user-list-item">
<p class="usa-body user-list-item-blank hint">You have not added any text message senders yet</p>
<p class="usa-body user-list-item-blank usa-hint">You have not added any text message senders yet</p>
</div>
{% endif %}
{% for item in current_service.sms_senders_with_hints %}
@@ -53,7 +53,7 @@
</div>
{% if current_user.has_permissions(ServicePermission.MANAGE_SERVICE) %}
<div class="grid-row bottom-gutter">
<div class="grid-row margin-bottom-3">
<div class="grid-col-12">
{{ usaButton({
"element": "a",

View File

@@ -12,7 +12,7 @@
{{ page_header("Audit events") }}
{% if show_navigation %}
<div class="bottom-gutter">
<div class="margin-bottom-3">
{{ pill(
[
('All', None, url_for('main.history', service_id=current_service.id), None),
@@ -26,10 +26,10 @@
{% endif %}
{% for day, events in days %}
<h2 class="heading-small top-gutter">
<h2 class="font-heading-md top-gutter">
{{ events[0].time|format_date_human|title }}
</h2>
<ul class="bottom-gutter">
<ul class="margin-bottom-3">
{% for event in events %}
<li class="history-list-item">
<div class="grid-row">

View File

@@ -5,11 +5,11 @@
</div>
<div class="grid-col-12">
{% if template._template.archived %}
<p class="hint">
<p class="usa-hint">
This template was deleted {{ template._template.updated_at|format_datetime_relative }}.
</p>
{% elif not current_user.has_permissions(ServicePermission.SEND_MESSAGES, 'manage_api_keys', ServicePermission.MANAGE_TEMPLATES, ServicePermission.MANAGE_SERVICE) or not user_has_template_permission %}
<p class="top-gutter-1-3 {% if template.template_type != 'sms' %}bottom-gutter{% endif %}">
<p class="top-gutter-1-3 {% if template.template_type != 'sms' %}margin-bottom-3{% endif %}">
If you need to send this
{{ 1|message_count_label(template.template_type, suffix='') }}
or edit this template, contact your manager.

View File

@@ -1,6 +1,6 @@
<div class="grid-col-12">
<h2 class="message-name">{{ template.name }}</h2>
<p class="hint">
<p class="usa-hint">
{% if template.get_raw('version', 1) > 1 %}
Edit made {% if template.get_raw('updated_at', None) %}{{ template.get_raw('updated_at')|format_datetime_normal }}{% endif %}
{% else %}

View File

@@ -15,13 +15,15 @@
{%- endmacro %}
{% if template_list.template_folder_id and not template_list.templates_to_show %}
<p class="template-list-empty">
{% if template_list.folder_is_empty %}
This folder is empty
{% else %}
There are no {{ 1|message_count_label(template_type, suffix='') }} templates in this folder
{% endif %}
</p>
<div>
<p class="text-base">
{% if template_list.folder_is_empty %}
This folder is empty
{% else %}
There are no {{ 1|message_count_label(template_type, suffix='') }} templates in this folder
{% endif %}
</p>
</div>
{% else %}
<nav id="template-list" aria-label="Template list">
{% set checkboxes_data = [] %}
@@ -85,7 +87,7 @@
{% set checkbox_config = {
"html": label_content,
"label": {
"classes": "template-list-item-label margin-top-05",
"classes": "template-list-item-label margin-top-1",
},
"id": "templates-or-folder-" ~ item.id,
"classes": "template-list-item template-list-item-with-checkbox {}".format(
@@ -100,7 +102,7 @@
<li
class="template-list-item {%- if item.ancestors %} template-list-item-hidden-by-default {%- else %} template-list-item-without-ancestors{%- endif %}">
{{ item_link_content }}
<p class="template-list-item-hint">
<p class="usa-hint margin-top-1">
{{ item.hint }}
</p>
</li>

View File

@@ -18,7 +18,7 @@
{% if not templates_and_folders.templates_to_show %}
{% if current_user.has_permissions(ServicePermission.MANAGE_TEMPLATES) %}
<p class="bottom-gutter">
<p class="margin-bottom-3">
You need a template before you can send text messages.
</p>
{{ usaButton({

View File

@@ -31,36 +31,42 @@
{% else %}
<div class="grid-row flex-column">
<h1 class="font-body-2xl line-height-sans-2 margin-bottom-1 margin-top-0" id="page-title">{{page_title}}</h1>
<div class="{% if current_user.has_permissions(ServicePermission.MANAGE_TEMPLATES) %} grid-col-10 {% else %} grid-col-12 {% endif %}">
<p class="margin-top-0 margin-bottom-4" id="page-description">
Every message starts with a template. To send, choose or create a template.
</p>
{{ folder_path(
folders=template_folder_path,
service_id=current_service.id,
template_type=template_type,
current_user=current_user
) }}
</div>
{% if current_user.has_permissions(ServicePermission.MANAGE_TEMPLATES) and current_template_folder_id and user_has_template_folder_permission %}
<div class="grid-col-2">
<a href="{{ url_for('.manage_template_folder', service_id=current_service.id, template_folder_id=current_template_folder_id) }}" class="usa-link folder-heading-manage-link">Manage this folder<span class="usa-sr-only">Manage this folder</span></a>
<div class="grid-row">
<div class="grid-col-12">
<h2 class="font-body-2xl line-height-sans-2 margin-0" id="page-title">{{page_title}}</h2>
<div class="grid-row">
<div class="{% if current_user.has_permissions(ServicePermission.MANAGE_TEMPLATES) and current_template_folder_id and user_has_template_folder_permission %}grid-col-10{% else %}grid-col-12{% endif %}">
<p class="margin-bottom-4" id="page-description">
Every message starts with a template. To send, choose or create a template.
</p>
{{ folder_path(
folders=template_folder_path,
service_id=current_service.id,
template_type=template_type,
current_user=current_user
) }}
</div>
{% if current_user.has_permissions(ServicePermission.MANAGE_TEMPLATES) and current_template_folder_id and user_has_template_folder_permission %}
<div class="grid-col-2 text-right">
<a href="{{ url_for('.manage_template_folder', service_id=current_service.id, template_folder_id=current_template_folder_id) }}" class="usa-link">Manage this folder</a>
</div>
{% endif %}
</div>
{% endif %}
</div>
</div>
{% endif %}
{% if show_template_nav %}
<div class="bottom-gutter-2-3">
<div class="margin-y-3">
{{ pill(template_nav_items, current_value=template_type, show_count=False) }}
</div>
{% endif %}
{{ live_search(target_selector='#template-list .template-list-item', show=show_search_box, form=search_form) }}
<div class="js-live-search-no-results js-hidden">
<p class="usa-body margin-top-2">No templates found</p>
<div class="js-live-search-no-results js-hidden margin-top-3">
<div class="padding-3 bg-base-lightest radius-md">
<p class="text-base margin-0">No templates found</p>
</div>
</div>
{% if current_user.has_permissions(ServicePermission.MANAGE_TEMPLATES) and user_has_template_folder_permission %}

View File

@@ -13,7 +13,7 @@
{% if show_redaction_message %}
<div class="bottom-gutter">
<div class="margin-bottom-3">
{% call banner_wrapper(type='dangerous', subhead='Are you sure you want to hide all personalized and conditional content after sending for increased privacy protection?') %}
<ul class="list list-bullet">
<li>
@@ -64,24 +64,25 @@
{% if current_user.has_permissions(ServicePermission.MANAGE_TEMPLATES) and user_has_template_permission %}
<h2 class="margin-bottom-1 font-body-lg">More actions</h2>
<ul class="usa-list usa-list--unstyled">
{% if not template._template.archived %}
<li>
<a class="usa-link margin-right-3"
href="{{ url_for('.delete_service_template', service_id=current_service.id, template_id=template.id) }}">
Delete this template
</a>
</li>
{% endif %}
{% if not template._template.redact_personalisation %}
<li>
<a class="usa-link"
<p class="margin-bottom-1">For increased privacy protection:</p>
<a class="usa-button usa-button--outline"
href="{{ url_for('.confirm_redact_template', service_id=current_service.id, template_id=template.id) }}">
Hide all personalized and conditional content after sending
</a> for increased privacy protection
Hide personalized content after sending
</a>
</li>
{% else %}
<li>
<p class="hint">Personalization is hidden after sending</p>
<p class="usa-hint">Personalization is hidden after sending</p>
</li>
{% endif %}
{% if not template._template.archived %}
<li class="margin-top-2">
<a class="usa-button usa-button--secondary"
href="{{ url_for('.delete_service_template', service_id=current_service.id, template_id=template.id) }}">
Delete this template
</a>
</li>
{% endif %}
</ul>

View File

@@ -28,9 +28,6 @@
<p> Notify.gov will:</p>
<ul class="list list-bullet">
<li>send all the messages you pass to us, as long as they meet our guidelines</li>
<!-- <li>
show how Notify is performing (through our <a class="usa-link" href="{{ url_for('main.performance') }}">performance</a> and <a class="usa-link" href="https://status.notifications.service.gov.uk/">status</a> page)
</li> -->
<li>keep your data <a class="usa-link" href="{{ url_for('.security') }}">secure</a></li>
<li>give you one months notice by email if we change our terms of use or delivery providers</li>
</ul>

View File

@@ -21,7 +21,7 @@
<div class='grid-row'>
<div class='grid-col-12'>
<h2 class='heading-small margin-bottom-1'>Text message parts</h2>
<h2 class='font-heading-md margin-bottom-1'>Text message parts</h2>
<div class="keyline-block">
You have sent
{{ big_number(sms_sent, 'text message parts of your', smaller=True) }}
@@ -43,7 +43,7 @@
</div>
</div>
{# <div class='grid-col-6'>
<h2 class='heading-small'>Emails</h2>
<h2 class='font-heading-md'>Emails</h2>
<div class="keyline-block">
{{ big_number(emails_sent, 'email disabled during SMS pilot', smaller=True) }}
{{ big_number("", '', smaller=True) }}