Merge branch 'main' of https://github.com/GSA/notifications-admin into notify-786

This commit is contained in:
Andrew Shumway
2023-11-06 12:48:18 -07:00
106 changed files with 2472 additions and 2684 deletions

View File

@@ -285,11 +285,22 @@ def init_app(application):
@application.context_processor
def _attach_current_global_daily_messages():
remaining_global_messages = 0
if current_app:
global_limit = current_app.config["GLOBAL_SERVICE_MESSAGE_LIMIT"]
global_messages_count = service_api_client.get_global_notification_count()
remaining_global_messages = global_limit - global_messages_count
if request.view_args:
service_id = request.view_args.get(
"service_id", session.get("service_id")
)
else:
service_id = session.get("service_id")
if service_id:
global_limit = current_app.config["GLOBAL_SERVICE_MESSAGE_LIMIT"]
global_messages_count = (
service_api_client.get_global_notification_count(service_id)
)
remaining_global_messages = global_limit - global_messages_count.get(
"count"
)
return {"daily_global_messages_remaining": remaining_global_messages}
@application.before_request
@@ -321,7 +332,7 @@ def make_session_permanent():
"""
Make sessions permanent. By permanent, we mean "admin app sets when it expires". Normally the cookie would expire
whenever you close the browser. With this, the session expiry is set in `config['PERMANENT_SESSION_LIFETIME']`
(20 hours) and is refreshed after every request. IE: you will be logged out after twenty hours of inactivity.
(30 min) and is refreshed after every request. IE: you will be logged out after thirty minutes of inactivity.
We don't _need_ to set this every request (it's saved within the cookie itself under the `_permanent` flag), only
when you first log in/sign up/get invited/etc, but we do it just to be safe. For more reading, check here:

View File

@@ -0,0 +1,65 @@
window.GOVUK = window.GOVUK || {};
window.GOVUK.Modules = window.GOVUK.Modules || {};
window.GOVUK.Modules.TimeoutPopup = window.GOVUK.Modules.TimeoutPopup || {};
(function(global) {
"use strict";
const sessionTimer = document.getElementById("sessionTimer");
let intervalId = null;
function checkTimer(timeTillSessionEnd) {
var now = new Date().getTime();
var difference = timeTillSessionEnd - now;
var minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((difference % (1000 * 60)) / 1000);
document.getElementById("timeLeft").innerHTML = + minutes + "m " + seconds + "s";
showTimer();
document.getElementById("logOutTimer").addEventListener("click", signoutUser);
document.getElementById("extendSessionTimer").addEventListener("click", extendSession);
if (difference < 0) {
clearInterval(intervalId);
intervalId = null;
closeTimer();
expireUserSession();
}
}
function expireUserSession() {
var signOutLink = '/sign-out?next=' + window.location.pathname;
window.location.href = signOutLink;
}
function signoutUser() {
window.location.href = '/sign-out';
}
function extendSession() {
window.location.reload();
}
function showTimer() {
sessionTimer.showModal();
}
function closeTimer() {
sessionTimer.close();
}
function setSessionTimer() {
var timeTillSessionEnd = new Date().getTime() + (5 * 60 * 1000);
intervalId = setInterval(checkTimer, 1000, timeTillSessionEnd);
}
if (document.getElementById("timeLeft") !== null) {
setTimeout(setSessionTimer, 25 * 60 * 1000);
}
global.GOVUK.Modules.TimeoutPopup.checkTimer = checkTimer;
global.GOVUK.Modules.TimeoutPopup.expireUserSession = expireUserSession;
global.GOVUK.Modules.TimeoutPopup.signoutUser = signoutUser;
global.GOVUK.Modules.TimeoutPopup.extendSession = extendSession;
global.GOVUK.Modules.TimeoutPopup.showTimer = showTimer;
global.GOVUK.Modules.TimeoutPopup.closeTimer = closeTimer;
})(window);

View File

@@ -414,7 +414,6 @@ details form {
display: block;
box-sizing: border-box;
position: relative;
margin: 0;
padding: 4px;
overflow: hidden;
line-height: 1.6;

View File

@@ -54,7 +54,7 @@ class Config(object):
EMAIL_EXPIRY_SECONDS = 3600 # 1 hour
INVITATION_EXPIRY_SECONDS = 3600 * 24 * 2 # 2 days - also set on api
EMAIL_2FA_EXPIRY_SECONDS = 1800 # 30 Minutes
PERMANENT_SESSION_LIFETIME = 20 * 60 * 60 # 20 hours
PERMANENT_SESSION_LIFETIME = 1800 # 30 Minutes
SEND_FILE_MAX_AGE_DEFAULT = 365 * 24 * 60 * 60 # 1 year
REPLY_TO_EMAIL_ADDRESS_VALIDATION_TIMEOUT = 45
ACTIVITY_STATS_LIMIT_DAYS = 7

View File

@@ -227,7 +227,7 @@ def terms():
)
@main.route("/features/using-notify")
@main.route("/features/using_notify")
@user_is_logged_in
def using_notify():
return (

View File

@@ -61,6 +61,82 @@ class HeaderNavigation(Navigation):
"message_status",
"guidance_index",
},
"accounts-or-dashboard": {
"conversation",
"inbox",
"monthly",
"service_dashboard",
"template_usage",
"view_notification",
"view_notifications",
"action_blocked",
"add_service_template",
"check_messages",
"check_notification",
"choose_template",
"choose_template_to_copy",
"confirm_redact_template",
"conversation_reply",
"copy_template",
"delete_service_template",
"edit_service_template",
"manage_template_folder",
"send_messages",
"send_one_off",
"send_one_off_step",
"send_one_off_to_myself",
"set_sender",
"set_template_sender",
"view_template",
"view_template_version",
"view_template_versions",
"uploads",
"view_job",
"view_jobs",
"confirm_edit_user_email",
"confirm_edit_user_mobile_number",
"edit_user_email",
"edit_user_mobile_number",
"edit_user_permissions",
"invite_user",
"manage_users",
"remove_user_from_service",
"usage",
"email_branding_govuk",
"email_branding_govuk_and_org",
"email_branding_organization",
"email_branding_request",
"email_branding_something_else",
"estimate_usage",
"link_service_to_organization",
"request_to_go_live",
"service_add_email_reply_to",
"service_add_sms_sender",
"service_confirm_delete_email_reply_to",
"service_confirm_delete_sms_sender",
"service_edit_email_reply_to",
"service_edit_sms_sender",
"service_email_reply_to",
"service_name_change",
"service_preview_email_branding",
"service_set_auth_type",
"service_set_channel",
"send_files_by_email_contact_details",
"service_set_email_branding",
"service_set_inbound_number",
"service_set_inbound_sms",
"service_set_international_sms",
"service_set_reply_to_email",
"service_set_sms_prefix",
"service_verify_reply_to_address",
"service_verify_reply_to_address_updates",
"service_settings",
"service_sms_senders",
"set_free_sms_allowance",
"set_message_limit",
"set_rate_limit",
"submit_request_to_go_live",
},
"pricing": {
"how_to_pay",
"billing_details",

View File

@@ -1,7 +1,5 @@
from datetime import datetime
from notifications_utils.clients.redis import daily_total_cache_key
from app.extensions import redis_client
from app.notify_client import NotifyAdminAPIClient, _attach_current_user, cache
@@ -497,11 +495,8 @@ class ServiceAPIClient(NotifyAdminAPIClient):
return int(count)
def get_global_notification_count(self):
# if cache is not set, or not enabled, return 0
count = redis_client.get(daily_total_cache_key()) or 0
return int(count)
def get_global_notification_count(self, service_id):
return self.get("/service/{}/notification-count".format(service_id))
service_api_client = ServiceAPIClient()

View File

@@ -23,7 +23,7 @@
<meta property="og:site_name" content="Notify.gov">
<meta property="og:image" content="{{ asset_url('images/usa-opengraph-image.png') }}">
{% endblock %}
<!-- <script type="text/javascript" src="{{ asset_url('js/gtm_head.js') }}"></script> -->
<script type="text/javascript" src="{{ asset_url('js/gtm_head.js') }}"></script>
{% endblock %}
{% block pageTitle %}
@@ -43,6 +43,11 @@
{% if current_user.is_authenticated %}
{% if current_user.platform_admin %}
{% set navigation = [
{
"href": url_for("main.show_accounts_or_dashboard"),
"text": "Current service",
"active": header_navigation.is_selected('accounts-or-dashboard')
},
{
"href": url_for('main.get_started'),
"text": "Using Notify",
@@ -75,6 +80,11 @@
] %}
{% else %}
{% set navigation = [
{
"href": url_for("main.show_accounts_or_dashboard"),
"text": "Current service",
"active": header_navigation.is_selected('accounts-or-dashboard')
},
{
"href": url_for('main.get_started'),
"text": "Using Notify",
@@ -92,7 +102,7 @@
},
{
"href": url_for('main.user_profile'),
"text": current_user.name,
"text": "User profile",
"active": header_navigation.is_selected('user-profile')
},
{
@@ -137,7 +147,6 @@
{% endblock %}
{% block footer %}
{% if current_service and current_service.research_mode %}
{% set meta_suffix = 'Built by the <a href="https://www.gsa.gov/about-us/organization/federal-acquisition-service/technology-transformation-services/tts-solutions" class="usa-link">Technology Transformation Services</a><span id="research-mode" class="research-mode">research mode</span>' %}
@@ -216,8 +225,45 @@
"html": meta_suffix
}
}) }}
{% if current_user.is_authenticated %}
{% block sessionUserWarning %}
<dialog class="usa-modal" id="sessionTimer" aria-labelledby="sessionTimerHeading" aria-describedby="timerWarning">
<div class="usa-modal__content">
<div class="usa-modal__main">
<h2 class="usa-modal__heading" id="sessionTimerHeading">
Your session will end soon.
<span class="usa-sr-only">Please choose to extend your session or sign out. Your session will expire in 5 minutes or less.</span>
</h2>
<div class="usa-prose">
<p>You have been inactive for too long.
Your session will expire in <span id="timeLeft" role="timer"></span>.
</p>
</div>
<div class="usa-modal__footer">
<ul class="usa-button-group">
<li class="usa-button-group__item">
<button type="button" class="usa-button" id="extendSessionTimer" data-close-modal>
Extend Session
</button>
</li>
<li class="usa-button-group__item">
<button type="button" class="usa-button usa-button--unstyled padding-105 text-center" id="logOutTimer"
data-close-modal>
Sign out
</button>
</li>
</ul>
</div>
</div>
</div>
</dialog>
{% endblock %}
{% endif %}
{% endblock %}
{% block bodyEnd %}
{% block extra_javascripts %}
{% endblock %}
@@ -225,4 +271,7 @@
<script type="text/javascript" src="{{ asset_url('javascripts/all.js') }}"></script>
<script type="text/javascript" src="{{ asset_url('js/uswds.min.js') }}"></script>
<!--<![endif]-->
{% endblock %}

View File

@@ -1,4 +1,4 @@
<div {%- if params.id %} id="{{ params.id }}"{% endif %} class="govuk-inset-text {%- if params.classes %} {{ params.classes }}{% endif %}"
<div {%- if params.id %} id="{{ params.id }}"{% endif %} class="bg-base-lightest padding-y-1 padding-x-2 {%- if params.classes %} {{ params.classes }}{% endif %}"
{%- for attribute, value in params.attributes %} {{attribute}}="{{value}}"{% endfor %}>
{{ params.html | safe if params.html else params.text }}
</div>

View File

@@ -4,16 +4,10 @@
<div class="grid-row">
<div class="grid-col-8">
<h1 class="heading-large">
Sorry, theres a problem with Notify.gov
Sorry, we can't deliver what you asked for right now.
</h1>
<p class="usa-body">
Try again later.
</p>
<!-- <p class="usa-body">
You can check our <a class="usa-link" href="https://status.notifications.service.gov.uk">system status</a> page to see if there are any known issues.
</p> -->
<p class="usa-body">
To report a problem, please email <a class="usa-link" href="mailto:notify-support@gsa.gov">notify-support@gsa.gov</a>.
Please try again later or <a class="usa-link" href="mailto:notify-support@gsa.gov"></a>email us</a> for more information.</p>
</p>
</div>
</div>

View File

@@ -1,13 +1,15 @@
{% if help %}
{% include 'partials/tour.html' %}
{% else %}
<nav class="nav margin-bottom-5">
<nav class="nav">
<a class="usa-button margin-top-1 margin-bottom-5 width-full"
href="{{ url_for('.choose_template', service_id=current_service.id) }}">Send messages</a>
<ul class="usa-sidenav">
{% if current_user.has_permissions() %}
{% if current_user.has_permissions('view_activity') %}
<li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('dashboard') }}" href="{{ url_for('.service_dashboard', service_id=current_service.id) }}">Dashboard</a></li>
{% endif %}
<li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('templates') }}" href="{{ url_for('.choose_template', service_id=current_service.id) }}">Send messages</a></li>
{# <li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('templates') }}" href="{{ url_for('.choose_template', service_id=current_service.id) }}">Send messages</a></li> #}
{% if not current_user.has_permissions('view_activity') %}
<li class="usa-sidenav__item"><a class="{{ casework_navigation.is_selected('sent-messages') }}" href="{{ url_for('.view_notifications', service_id=current_service.id, status='sending,delivered,failed') }}">Sent messages</a></li>
{% endif %}
@@ -27,8 +29,4 @@
{% endif %}
</ul>
</nav>
<div>
<p class="usa--body bold margin-bottom-1">Messages Left Across Services</p>
<p>{{ daily_global_messages_remaining }}</p>
</div>
{% endif %}

View File

@@ -1,8 +1,14 @@
<h2 class="font-body-lg">Message length</h2>
<p class="usa-body">
If your message is long then it will
cost more.
</p>
<p class="usa-body">
See <a class="usa-link" href="{{ url_for('.pricing') }}">pricing</a> for details.
</p>
<h3 class="usa-accordion__heading">
<button type="button" class="usa-accordion__button" aria-expanded="false" aria-controls="message-length">
Message length
</button>
</h3>
<div id="message-length" class="usa-accordion__content usa-prose">
<p class="usa-body">
If your message is long then it will
cost more.
</p>
<p class="usa-body">
See <a class="usa-link" href="{{ url_for('.pricing') }}">pricing</a> for details.
</p>
</div>

View File

@@ -1,9 +1,15 @@
{% from "components/components/inset-text/macro.njk" import usaInsetText %}
<h2 class="font-body-lg">Links and URLs</h2>
<p class="bottom-gutter-1-3">
Always use full URLs, starting with https://. For example:
{{ usaInsetText({
"text": "Apply now at https://www.usa.gov/example",
"classes": "usa-body"})
}}
<h3 class="usa-accordion__heading">
<button type="button" class="usa-accordion__button" aria-expanded="false" aria-controls="links-and-urls">
Links and URLs
</button>
</h3>
<div id="links-and-urls" class="usa-accordion__content usa-prose">
<p>
Always use full URLs, starting with https://. For example:
{{ usaInsetText({
"text": "Apply now at https://www.usa.gov/example",
"classes": "usa-body"})
}}
</div>

View File

@@ -1,21 +1,25 @@
{% from "components/components/inset-text/macro.njk" import usaInsetText %}
<h2 class="font-body-lg">
Optional content
</h2>
<p class="usa-body">
Use double brackets and ?? to define optional content.
</p>
<p class="bottom-gutter-1-3">
For example if you only want to show something to people who are under
18:
</p>
{{ usaInsetText({
<h3 class="usa-accordion__heading">
<button type="button" class="usa-accordion__button" aria-expanded="false" aria-controls="m-a2">
Optional content
</button>
</h3>
<div id="m-a2" class="usa-accordion__content usa-prose">
<p class="usa-body">
Use double brackets and ?? to define optional content.
</p>
<p class="bottom-gutter-1-3">
For example if you only want to show something to people who are under
18:
</p>
{{ usaInsetText({
"text": "((under18??Please get your application signed by a parent or
guardian.))",
"classes": "usa-body"})
}}
<p class="usa-body">
For each person you send this message to, specify yes or no to
show or hide this content.
</p>
}}
<p class="usa-body">
For each person you send this message to, specify yes or no to
show or hide this content.
</p>
</div>

View File

@@ -1,12 +0,0 @@
{% from "components/components/inset-text/macro.njk" import usaInsetText %}
<h2 class="font-body-lg">
Personalization
</h2>
<p class="bottom-gutter-1-3">
Use double brackets to personalize your message:
</p>
{{ usaInsetText({
"text": "Hello ((first name)), your reference is ((ref number))",
"classes": ""})
}}

View File

@@ -0,0 +1,17 @@
{% from "components/components/inset-text/macro.njk" import usaInsetText %}
<h3 class="usa-accordion__heading">
<button type="button" class="usa-accordion__button" aria-expanded="false" aria-controls="personalization">
Personalization
</button>
</h3>
<div id="personalization" class="usa-accordion__content usa-prose">
<p class="bottom-gutter-1-3">
Use double brackets to personalize your message:
</p>
{{ usaInsetText({
"text": "Hello ((first name)), your reference is ((ref number))",
"classes": ""})
}}
</div>

View File

@@ -7,7 +7,7 @@
</div>
{% endmacro %}
<div class="navigation-service margin-top-2 display-flex flex-align-end flex-justify border-bottom padding-bottom-1">
<div class="navigation-service margin-top-5 display-flex flex-align-end flex-justify border-bottom padding-bottom-1">
{% if current_service.organization_id %}
{% if current_user.platform_admin or
(current_user.belongs_to_organization(current_service.organization_id) and current_service.live) %}

View File

@@ -2,22 +2,34 @@
<div class='grid-row grid-gap ajax-block-container'>
<div class='grid-col-12'>
<div class="keyline-block">
{% if sms_cost %}
{{ big_number(
sms_cost,
'spent on text messages',
currency="$",
smaller=True
) }}
{% else %}
{{ big_number(sms_allowance_remaining, 'free text messages left', smaller=True) }}
{% endif %}
</div>
<table class="usa-table usa-table--borderless margin-top-1 margin-bottom-5">
<caption class="usa-sr-only">
Daily
</caption>
<thead>
<tr>
<th scope="col">Usage</th>
<th scope="col">Remaining</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ big_number(40000 - sms_allowance_remaining, smaller=True) }}</td>
<td>
{% if sms_cost %}
{{ big_number(
sms_cost,
'spent on text messages',
currency="$",
smaller=True
) }}
{% else %}
{{ big_number(sms_allowance_remaining, smaller=True) }}
{% endif %}
</td>
</tr>
</tbody>
</table>
</div>
<!-- <div class='grid-col-6 pilot-disabled'>
<div class="keyline-block">
{{ big_number("0", 'email disabled during SMS pilot', smaller=True) }}
</div>
</div> -->
</div>

View File

@@ -19,9 +19,10 @@
{{ ajax_block(partials, updates_url, 'upcoming') }}
<h2 class="font-body-lg margin-top-0 margin-bottom-1">
In the last seven days
<h2 class="font-body-xl margin-0">
Messages sent
</h2>
<p class="margin-top-0">In the last seven days</p>
{{ ajax_block(partials, updates_url, 'inbox') }}
@@ -29,15 +30,37 @@
{{ ajax_block(partials, updates_url, 'template-statistics') }}
<h2 class="margin-top-4 margin-bottom-1">Usage</h2>
<h3 class="margin-bottom-0">Daily</h3>
<p class="margin-0">Across all services</p>
<table class="usa-table usa-table--borderless margin-top-1 margin-bottom-5">
<caption class="usa-sr-only">
Daily
</caption>
<thead>
<tr>
<th scope="col">Usage</th>
<th scope="col">Remaining</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ 5000 - daily_global_messages_remaining }}</td>
<td>
{{ daily_global_messages_remaining }}
</td>
</tr>
</tbody>
</table>
{% if current_user.has_permissions('manage_service') %}
<h2 class='font-body-lg margin-bottom-0'>This year</h2>
<h3 class='margin-bottom-0'>2023</h3>
{{ ajax_block(partials, updates_url, 'usage') }}
{{ show_more(
url_for(".usage", service_id=current_service['id']),
'See usage'
'See all usage'
) }}
{% endif %}
</div>
{% endblock %}

View File

@@ -1,4 +1,4 @@
<h2 class="font-body-lg">Get started</h2>
<a class="usa-button" href="{{ url_for('.choose_template', service_id=current_service.id) }}">
<h2 class="font-body-lg margin-top-0 margin-bottom-1">Get started</h2>
<a class="usa-button margin-bottom-5" href="{{ url_for('.choose_template', service_id=current_service.id) }}">
Create your first template
</a>

View File

@@ -37,7 +37,7 @@
</div>
<div class="grid-col-12">
{% include "partials/templates/guidance-formatting.html" %}
{% include "partials/templates/guidance-personalisation.html" %}
{% include "partials/templates/guidance-personalization.html" %}
{% include "partials/templates/guidance-optional-content.html" %}
{% include "partials/templates/guidance-links.html" %}
{% include "partials/templates/guidance-send-a-document.html" %}

View File

@@ -20,11 +20,9 @@
{{ page_header('{} text message template'.format(heading_action)) }}
{{ usaAlert({
"type": "info",
"text": "Don't worry, saving the template will not send",
"classes": "margin-top-2 usa-button--secondary"
}) }}
<a class="usa-link display-inline-flex margin-top-05" href="#help">
How to customize your message
</a>
{% if current_service.prefix_sms %}
{% set content_hint = 'Your service name will be added to the start of your message. You can turn this off in Settings.' %}
@@ -32,7 +30,7 @@
{% call form_wrapper() %}
<div class="grid-row">
<div class="grid-col-8">
<div class="tablet:grid-col-9 mobile-lg:grid-col-12">
{{ form.name(param_extensions={
"extra_form_group_classes": "margin-bottom-2",
"hint": {"text": "Your recipients will not see this"}
@@ -50,22 +48,36 @@
{{ form.process_type }}
{% endif %}
</div>
<div class="grid-col-12">
<div class="template-content-count">
<div data-module="update-status" data-target="template_content" data-updates-url="{{ url_for('.count_content_length', service_id=current_service.id, template_type='sms') }}" aria-live="polite">
&nbsp;
<div class="grid-row">
<div class="grid-col-12">
<div class="template-content-count">
<div data-module="update-status" data-target="template_content"
data-updates-url="{{ url_for('.count_content_length', service_id=current_service.id, template_type='sms') }}"
aria-live="polite">
&nbsp;
</div>
</div>
</div>
{{ page_footer('Save') }}
<p class="usa-hint">
After saving, you'll have the option to send 🚀
</p>
</div>
<div class="grid-col-12">
{% include "partials/templates/guidance-personalisation.html" %}
{% include "partials/templates/guidance-optional-content.html" %}
{% include "partials/templates/guidance-links.html" %}
{% include "partials/templates/guidance-character-count.html" %}
<div class="grid-row width-full">
<div class="tablet:grid-col-2 mobile-lg:grid-col-12">
{{ page_footer('Save') }}
</div>
<div class="tablet:grid-col-10 mobile-lg:grid-col-12">
<p class="usa-hint margin-top-5 tablet:margin-left-neg-2">
After saving, you'll have the option to send.
</p>
</div>
</div>
<div class="tablet:grid-col-9 mobile-lg:grid-col-12">
<h2 id="help" class="font-body-xl margin-top-2">How to customize your message</h2>
<div class="usa-accordion usa-accordion--bordered usa-accordion--multiselectable maxw-mobile-lg" data-allow-multiple>
{% include "partials/templates/guidance-personalization.html" %}
{% include "partials/templates/guidance-optional-content.html" %}
{% include "partials/templates/guidance-links.html" %}
{% include "partials/templates/guidance-character-count.html" %}
</div>
</div>
</div>
{% endcall %}

View File

@@ -21,7 +21,10 @@
<div class='grid-row'>
<div class='grid-col-12'>
<h2 class='heading-small'>Text messages</h2>
<h2 class="heading-small margin-bottom-1">Daily messages across all services</h2>
<p class="margin-0">You have sent {{ 5000 - daily_global_messages_remaining }} of your 5000 daily messages allowance.</p>
<p class="margin-0"></p>You have {{ daily_global_messages_remaining }} messages remaining.</p>
<h2 class='heading-small margin-bottom-1'>Text messages</h2>
<div class="keyline-block">
You have sent
{{ big_number(sms_sent, 'messages of your', smaller=True) }}

View File

@@ -3,16 +3,16 @@
{% from "components/table.html" import mapping_table, row, text_field, optional_text_field, edit_field, field, boolean_field with context %}
{% block per_page_title %}
Your profile
User profile
{% endblock %}
{% block maincolumn_content %}
<h1 class="font-body-2xl margin-bottom-3">Your profile</h1>
<h1 class="font-body-2xl margin-bottom-3">User profile</h1>
<div class="body-copy-table">
{% call mapping_table(
caption='Your profile',
caption='User profile',
field_headings_visible=False,
caption_visible=False
) %}

View File

@@ -4,9 +4,9 @@
{% block beforeContent %}
{% if current_service and current_service.active and current_user.is_authenticated and current_user.belongs_to_service(current_service.id) %}
<div class="navigation-service usa-breadcrumb">
<!-- <div class="navigation-service usa-breadcrumb">
<a href="{{ url_for('main.show_accounts_or_dashboard') }}" class="usa-link usa-breadcrumb__link usa-breadcrumb-back-to">Back to {{ current_service.name }}</a>
</div>
</div> -->
{% endif %}
{% block backLink %}{% endblock %}
{% endblock %}

View File

@@ -63,6 +63,7 @@ def generate_notifications_csv(**kwargs):
from app import notification_api_client
from app.s3_client.s3_csv_client import s3download
current_app.logger.info("\n\n\n\nENTER generate_notifications_csv")
if "page" not in kwargs:
kwargs["page"] = 1
@@ -76,7 +77,16 @@ def generate_notifications_csv(**kwargs):
fieldnames = (
["Row number"]
+ original_column_headers
+ ["Template", "Type", "Sent by", "Job", "Status", "Time"]
+ [
"Template",
"Type",
"Sent by",
"Job",
"Carrier",
"Carrier Response",
"Status",
"Time",
]
)
else:
fieldnames = [
@@ -85,6 +95,8 @@ def generate_notifications_csv(**kwargs):
"Type",
"Sent by",
"Job",
"Carrier",
"Carrier Response",
"Status",
"Time",
]
@@ -96,7 +108,7 @@ def generate_notifications_csv(**kwargs):
**kwargs
)
for notification in notifications_resp["notifications"]:
current_app.logger.info(notification)
current_app.logger.info(f"\n\n{notification}")
if kwargs.get("job_id"):
values = (
[
@@ -111,6 +123,8 @@ def generate_notifications_csv(**kwargs):
notification["template_type"],
notification["created_by_name"],
notification["job_name"],
notification["carrier"],
notification["provider_response"],
notification["status"],
notification["created_at"],
]
@@ -122,6 +136,8 @@ def generate_notifications_csv(**kwargs):
notification["template_type"],
notification["created_by_name"] or "",
notification["job_name"] or "",
notification["carrier"],
notification["provider_response"],
notification["status"],
notification["created_at"],
]