Merge branch 'main' of https://github.com/GSA/notifications-admin into notify-678
@@ -2,6 +2,7 @@ import os
|
||||
import pathlib
|
||||
from functools import partial
|
||||
from time import monotonic
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
|
||||
import jinja2
|
||||
from flask import (
|
||||
@@ -36,7 +37,6 @@ from werkzeug.local import LocalProxy
|
||||
from app import proxy_fix
|
||||
from app.asset_fingerprinter import asset_fingerprinter
|
||||
from app.config import configs
|
||||
from app.custom_auth import CustomBasicAuth
|
||||
from app.extensions import redis_client, zendesk_client
|
||||
from app.formatters import (
|
||||
convert_to_boolean,
|
||||
@@ -121,7 +121,6 @@ from app.url_converters import (
|
||||
login_manager = LoginManager()
|
||||
csrf = CSRFProtect()
|
||||
talisman = Talisman()
|
||||
basic_auth = CustomBasicAuth()
|
||||
|
||||
|
||||
# The current service attached to the request stack.
|
||||
@@ -234,8 +233,6 @@ def create_app(application):
|
||||
login_manager.session_protection = None
|
||||
login_manager.anonymous_user = AnonymousUser
|
||||
|
||||
setup_basic_auth(application)
|
||||
|
||||
# make sure we handle unicode correctly
|
||||
redis_client.redis_store.decode_responses = True
|
||||
|
||||
@@ -254,6 +251,7 @@ def create_app(application):
|
||||
|
||||
|
||||
def init_app(application):
|
||||
application.before_request(redirect_notify_to_beta)
|
||||
application.before_request(load_service_before_request)
|
||||
application.before_request(load_organization_before_request)
|
||||
application.before_request(request_helper.check_proxy_header_before_request)
|
||||
@@ -332,6 +330,23 @@ def make_session_permanent():
|
||||
session.permanent = True
|
||||
|
||||
|
||||
def create_beta_url(url):
|
||||
url_created = urlparse(url)
|
||||
url_list = list(url_created)
|
||||
url_list[1] = "beta.notify.gov"
|
||||
url_for_redirect = urlunparse(url_list)
|
||||
return url_for_redirect
|
||||
|
||||
|
||||
def redirect_notify_to_beta():
|
||||
if (
|
||||
current_app.config["NOTIFY_ENVIRONMENT"] == "production"
|
||||
and "beta.notify.gov" not in request.url
|
||||
):
|
||||
url_to_beta = create_beta_url(request.url)
|
||||
return redirect(url_to_beta, 302)
|
||||
|
||||
|
||||
def load_service_before_request():
|
||||
if "/static/" in request.url:
|
||||
request_ctx.service = None
|
||||
@@ -565,7 +580,3 @@ def init_jinja(application):
|
||||
]
|
||||
jinja_loader = jinja2.FileSystemLoader(template_folders)
|
||||
application.jinja_loader = jinja_loader
|
||||
|
||||
|
||||
def setup_basic_auth(application):
|
||||
application.basic_auth = CustomBasicAuth(application)
|
||||
|
||||
@@ -12,23 +12,21 @@
|
||||
|
||||
<link rel="shortcut icon" sizes="16x16 32x32 48x48" href="/static/images/favicon.ico?de7abc5226925203ac10b0a4a94af949"
|
||||
type="image/x-icon" />
|
||||
<link rel="mask-icon" href="/static/images/govuk-mask-icon.svg?2afd125b1db96109388d4a0727312f3e" color="#0b0c0c">
|
||||
<link rel="mask-icon" href="/static/images/usa-mask-icon.svg?2afd125b1db96109388d4a0727312f3e" color="#F0F0F0">
|
||||
<link rel="apple-touch-icon" sizes="180x180"
|
||||
href="/static/images/govuk-apple-touch-icon-180x180.png?a0f7e1b728a42016b247dc54ee40d055">
|
||||
<link rel="apple-touch-icon" sizes="167x167"
|
||||
href="/static/images/govuk-apple-touch-icon-167x167.png?f636cb7d471fc6239d2241d75cbdabcb">
|
||||
<link rel="apple-touch-icon" sizes="152x152"
|
||||
href="/static/images/govuk-apple-touch-icon-152x152.png?40846d46aa37232e2b35065769ce567c">
|
||||
<link rel="apple-touch-icon" href="/static/images/govuk-apple-touch-icon.png?3c45daa1f1e716458e4da954b973002e">
|
||||
href="/static/images/apple-touch-icon.png?a0f7e1b728a42016b247dc54ee40d055">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/images/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/images/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/images/site.webmanifest">
|
||||
|
||||
<link rel="stylesheet" media="screen" href="/static/stylesheets/main.css?d077f86473501ab244de0b30600536ee" />
|
||||
<link rel="stylesheet" media="print" href="/static/stylesheets/print.css?28010888ca5719dc83d7c2c80f6ed2b2" />
|
||||
|
||||
<meta property="og:image" content="/static/images/govuk-opengraph-image.png">
|
||||
<meta property="og:image" content="/static/images/usa-opengraph-image.png">
|
||||
</head>
|
||||
|
||||
<body class="usa-template__body">
|
||||
<a href="#main-content" class="govuk-skip-link">Skip to main content</a>
|
||||
<a href="#main-content" class="usa-skip-link">Skip to main content</a>
|
||||
<header class="usa-header " role="banner" data-module="header">
|
||||
<div class="usa-header__container usa-width-container">
|
||||
|
||||
|
||||
BIN
app/assets/images/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/assets/images/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
app/assets/images/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/assets/images/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 283 B |
BIN
app/assets/images/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 384 B |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
1
app/assets/images/site.webmanifest
Normal file
@@ -0,0 +1 @@
|
||||
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
||||
4
app/assets/images/usa-mask-icon.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="680" height="680" viewBox="0 0 680 680" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M672 211H332V161L672 161V211ZM672 294H332V244H672V294ZM672 377H332V327H672V377ZM672 410V460H8V410H672ZM672 493V543H8V493H672Z" fill="#D83933"/>
|
||||
<path d="M8 161H299V377H8V161Z" fill="#3C3B6E"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 349 B |
BIN
app/assets/images/usa-opengraph-image.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
@@ -16,7 +16,7 @@
|
||||
// The label gets styled like a button and is used to hide the native file upload control. This is so that
|
||||
// users see a button that looks like the others on the site.
|
||||
//
|
||||
this.$form.find('label.file-upload-button').addClass('usa-button');
|
||||
this.$form.find('label.file-upload-button').addClass('usa-button margin-bottom-1');
|
||||
|
||||
// Clear the form if the user navigates back to the page
|
||||
$(window).on("pageshow", () => this.$form[0].reset());
|
||||
|
||||
@@ -9,48 +9,48 @@
|
||||
let states = {
|
||||
'initial': Hogan.compile(`
|
||||
{{#showNowAsDefault}}
|
||||
<div class="radio-select__column">
|
||||
<div class="radio-select__column margin-y-2">
|
||||
<div class="usa-radio">
|
||||
<input class="usa-radio__input" checked="checked" id="{{name}}-0" name="{{name}}" type="radio" value="">
|
||||
<label class="usa-radio__label" for="{{name}}-0">Now</label>
|
||||
</div>
|
||||
</div>
|
||||
{{/showNowAsDefault}}
|
||||
<div class="radio-select__column">
|
||||
<div class="radio-select__column margin-y-2">
|
||||
{{#categories}}
|
||||
<input type='button' class='govuk-button govuk-button--secondary radio-select__button--category' aria-expanded="false" value='{{.}}' />
|
||||
<input type='button' class='usa-button usa-button--outline radio-select__button--category' aria-expanded="false" value='{{.}}' />
|
||||
{{/categories}}
|
||||
</div>
|
||||
`),
|
||||
'choose': Hogan.compile(`
|
||||
{{#showNowAsDefault}}
|
||||
<div class="radio-select__column">
|
||||
<div class="radio-select__column margin-y-2">
|
||||
<div class="usa-radio">
|
||||
<input class="usa-radio__input" checked="checked" id="{{name}}-0" name="{{name}}" type="radio" value="">
|
||||
<label class="usa-radio__label" for="{{name}}-0">Now</label>
|
||||
</div>
|
||||
</div>
|
||||
{{/showNowAsDefault}}
|
||||
<div class="radio-select__column">
|
||||
<div class="radio-select__column margin-y-2">
|
||||
{{#choices}}
|
||||
<div class="usa-radio js-option">
|
||||
<input class="usa-radio__input" type="radio" value="{{value}}" id="{{id}}" name="{{name}}" />
|
||||
<label class="usa-radio__label" for="{{id}}">{{label}}</label>
|
||||
</div>
|
||||
{{/choices}}
|
||||
<input type='button' class='govuk-button govuk-button--secondary radio-select__button--done' aria-expanded='true' value='Done' />
|
||||
<input type='button' class='usa-button usa-button--outline radio-select__button--done' aria-expanded='true' value='Done' />
|
||||
</div>
|
||||
`),
|
||||
'chosen': Hogan.compile(`
|
||||
{{#showNowAsDefault}}
|
||||
<div class="radio-select__column">
|
||||
<div class="radio-select__column margin-y-2">
|
||||
<div class="usa-radio">
|
||||
<input class="usa-radio__input" id="{{name}}-0" name="{{name}}" type="radio" value="">
|
||||
<label class="usa-radio__label" for="{{name}}-0">Now</label>
|
||||
</div>
|
||||
</div>
|
||||
{{/showNowAsDefault}}
|
||||
<div class="radio-select__column">
|
||||
<div class="radio-select__column margin-y-2">
|
||||
{{#choices}}
|
||||
<div class="usa-radio">
|
||||
<input class="usa-radio__input" checked="checked" type="radio" value="{{value}}" id="{{id}}" name="{{name}}" />
|
||||
@@ -58,8 +58,8 @@
|
||||
</div>
|
||||
{{/choices}}
|
||||
</div>
|
||||
<div class="radio-select__column">
|
||||
<input type='button' class='govuk-button govuk-button--secondary radio-select__button--reset' aria-expanded='false' value='Choose a different time' />
|
||||
<div class="radio-select__column margin-y-2">
|
||||
<input type='button' class='usa-button usa-button--outline radio-select__button--reset' aria-expanded='false' value='Choose a different time' />
|
||||
</div>
|
||||
`)
|
||||
};
|
||||
|
||||
342
app/assets/sass/uswds/_legacy-styles.scss
Normal file
@@ -0,0 +1,342 @@
|
||||
@use "uswds-core" as *;
|
||||
|
||||
// SMS Box Style
|
||||
|
||||
.sms-message-wrapper {
|
||||
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 464px;
|
||||
box-sizing: border-box;
|
||||
padding: units(1);
|
||||
background: color('gray-cool-10');
|
||||
border: 1px solid color('gray-cool-10');
|
||||
border-radius: 5px;
|
||||
white-space: normal;
|
||||
margin: 0 0 units(1) 0;
|
||||
clear: both;
|
||||
word-wrap: break-word;
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
right: -20px;
|
||||
border: 10px solid transparent;
|
||||
border-left-width: 13px;
|
||||
border-right-width: 13px;
|
||||
border-bottom-color: color('gray-cool-10');
|
||||
border-left-color: color('gray-cool-10');
|
||||
transform: rotate(17deg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.sms-message-inbound {
|
||||
|
||||
.sms-message-wrapper {
|
||||
|
||||
&:after {
|
||||
border-left-color: transparent;
|
||||
border-bottom-color: color('gray-cool-10');
|
||||
border-right-color: color('gray-cool-10');
|
||||
right: auto;
|
||||
left: -20px;
|
||||
transform: rotate(17deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sms-message-sender {
|
||||
margin: units(1) 0 0;
|
||||
}
|
||||
|
||||
.sms-message-recipient {
|
||||
color: color('gray-cool-90');
|
||||
margin: 0 0 units(1);
|
||||
}
|
||||
|
||||
.sms-message-status {
|
||||
color: color('gray-cool-90');
|
||||
margin: -20px units(1) 20px units(1);
|
||||
}
|
||||
|
||||
.sms-message-status-outbound {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.sms-message-row {
|
||||
&:focus {
|
||||
outline: none;
|
||||
padding-top: 120px;
|
||||
margin-top: -120px;
|
||||
}
|
||||
}
|
||||
|
||||
.sms-message-reply-link {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
// File upload area
|
||||
|
||||
.page-footer {
|
||||
position: relative;
|
||||
margin-bottom: 30px;
|
||||
&-link {
|
||||
line-height: 40px;
|
||||
padding: 1px 0 0 15px;
|
||||
font-weight: normal;
|
||||
&:first-of-type {
|
||||
padding-left: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
&-delete-link-without-button {
|
||||
padding: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&-secondary-link {
|
||||
display: block;
|
||||
margin-top: units(1);
|
||||
}
|
||||
|
||||
&-right-aligned-link {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 9px; // align baseline with buttons
|
||||
&-without-button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__button {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.js-cancel {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__button--centred {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.file-upload {
|
||||
&-label,
|
||||
&-button-label {
|
||||
font-weight: bold;
|
||||
font-size: 19px;
|
||||
display: block;
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
|
||||
&-label .error-message,
|
||||
&-button-label.error-message {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&-field {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
// Hide normal upload form if we're adding a custom version with JS
|
||||
.js-enabled &-label,
|
||||
.js-enabled &-field,
|
||||
.js-enabled &-submit {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-alternate-link {
|
||||
display: inline-block;
|
||||
line-height: 35px;
|
||||
a {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.spreadsheet {
|
||||
|
||||
margin-bottom: units (1);
|
||||
|
||||
.table {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.usa-table--borderless thead th {
|
||||
border-top: 1px solid color('gray-cool-10');
|
||||
}
|
||||
|
||||
th,
|
||||
.table-field-index {
|
||||
background: color('gray-cool-10');
|
||||
border: 1px solid color('gray-cool-10');
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
border: 1px solid color('gray-cool-10');
|
||||
}
|
||||
|
||||
td {
|
||||
border-top: 0;
|
||||
// 194 is the width of the table * 1/3.5, so the overflow cuts off
|
||||
// at 3.5 columns wide.
|
||||
// 11 accounts for the padding of the table cell
|
||||
min-width: 194px - 11px;
|
||||
&:first-child {
|
||||
min-width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.fullscreen-fixed-table {
|
||||
z-index: 1000;
|
||||
.table-field-heading-first {
|
||||
background: color('gray-cool-10');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fullscreen {
|
||||
&-content {
|
||||
background: #FFFFFF;
|
||||
z-index: 10;
|
||||
overflow-y: hidden;
|
||||
box-sizing: border-box;
|
||||
margin: 0 0 units(1) 0;
|
||||
padding: 0 0 0 0;
|
||||
overflow: hidden;
|
||||
border-bottom: 1px solid color('gray-cool-10');
|
||||
.table {
|
||||
margin-bottom: 0;
|
||||
tr:last-child {
|
||||
td {
|
||||
border-bottom: 1px solid #FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
th,
|
||||
.table-field-error-label,
|
||||
.table-field-left-aligned {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
&-right-shadow {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 4px;
|
||||
height: 100%;
|
||||
z-index: 200;
|
||||
&.visible {
|
||||
&.with-transition {
|
||||
transition: box-shadow 0.6s ease-out;
|
||||
}
|
||||
box-shadow: inset -1px 0 0 0 color('gray-cool-10'), inset -3px 0 0 0 rgba(color('gray-cool-10'), 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&-scrollable-table {
|
||||
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
|
||||
.table-field-heading-first,
|
||||
.table-field-index {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.table-field-left-aligned {
|
||||
position: relative;
|
||||
z-index: 150;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar:horizontal {
|
||||
height: 11px;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 8px;
|
||||
border: 2px solid #FFFFFF;
|
||||
background-color: rgba(0, 0, 0, .5);
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&-fixed-table {
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
overflow: hidden;
|
||||
|
||||
.table-field-heading {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.table-field-left-aligned {
|
||||
width: 0;
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.table-field-heading-first,
|
||||
.table-field-index {
|
||||
transition: none;
|
||||
position: relative;
|
||||
z-index: 200;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
&-scrolled-table {
|
||||
padding-bottom: 20px;
|
||||
.table-field-heading-first,
|
||||
.table-field-index {
|
||||
transition: box-shadow 0.3s ease-in-out;
|
||||
box-shadow: 1px 0 0 0 color('gray-cool-10'), 3px 0 0 0 rgba(color('gray-cool-10'), 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
&-shim {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
z-index: 9;
|
||||
margin-bottom: 30px;
|
||||
pointer-events: none;
|
||||
& + .table-show-more-link {
|
||||
margin-top: -20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.js-focus-style {
|
||||
outline: 3px solid color("blue-40v");
|
||||
box-shadow: 0 0 0 7px color("blue-40v");
|
||||
*:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,9 @@ i.e.
|
||||
.usa-header--extended .usa-logo {
|
||||
font-family: family("sans");
|
||||
margin: units(4) 0;
|
||||
@include at-media-max('mobile-lg') {
|
||||
margin: units(4) 0 units(4) units(2);
|
||||
}
|
||||
img {
|
||||
@include at-media($theme-header-min-width) {
|
||||
width: 80px;
|
||||
@@ -33,10 +36,23 @@ i.e.
|
||||
}
|
||||
}
|
||||
|
||||
.usa-nav__primary > .usa-nav__primary-item > a {
|
||||
font-size: size("body", 4);
|
||||
.usa-banner__header-action {
|
||||
font-size: size("body", 2);
|
||||
}
|
||||
|
||||
.usa-nav__primary {
|
||||
&> .usa-nav__primary-item > a {
|
||||
font-size: size("body", 4);
|
||||
}
|
||||
&> .usa-nav__primary-item:last-child {
|
||||
margin-left: auto;
|
||||
@include u-margin-right(-4);
|
||||
}
|
||||
}
|
||||
|
||||
.usa-nav__primary
|
||||
|
||||
|
||||
h1 {
|
||||
font-weight: bold !important;
|
||||
}
|
||||
@@ -250,6 +266,19 @@ td.table-empty-message {
|
||||
background: color("green-cool-40v");
|
||||
display: flex;
|
||||
padding: units(1) units(2);
|
||||
&--failing {
|
||||
padding: 0;
|
||||
a.usa-link {
|
||||
color: white;
|
||||
background: color("red-warm-50v");
|
||||
padding: units(1) units(2);
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
&:hover {
|
||||
background: color("red-warm-60v");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.usa-table {
|
||||
@@ -443,16 +472,3 @@ details form {
|
||||
padding-left: 5px;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
// .textbox-colour-preview {
|
||||
// @include govuk-media-query($from: desktop) {
|
||||
// width: 38px;
|
||||
// height: 38px;
|
||||
// margin-left: 5px;
|
||||
// border-radius: 50%;
|
||||
// box-shadow: inset 0 0 0 1px rgba(govuk-colour("black"), 0.2);
|
||||
// display: inline-block;
|
||||
// vertical-align: top;
|
||||
// transition: background 0.3s ease-out;
|
||||
// }
|
||||
// }
|
||||
@@ -1,3 +1,4 @@
|
||||
@forward "uswds-theme";
|
||||
@forward "uswds";
|
||||
@forward "uswds-theme-custom-styles";
|
||||
@forward "uswds-theme-custom-styles";
|
||||
@forward "legacy-styles";
|
||||
@@ -28,8 +28,6 @@ class Config(object):
|
||||
# ZENDESK_API_KEY = getenv('ZENDESK_API_KEY')
|
||||
ROUTE_SECRET_KEY_1 = getenv("ROUTE_SECRET_KEY_1", "dev-route-secret-key-1")
|
||||
ROUTE_SECRET_KEY_2 = getenv("ROUTE_SECRET_KEY_2", "dev-route-secret-key-2")
|
||||
BASIC_AUTH_USERNAME = getenv("BASIC_AUTH_USERNAME")
|
||||
BASIC_AUTH_PASSWORD = getenv("BASIC_AUTH_PASSWORD")
|
||||
|
||||
NR_ACCOUNT_ID = getenv("NR_ACCOUNT_ID")
|
||||
NR_TRUST_KEY = getenv("NR_TRUST_KEY")
|
||||
@@ -101,7 +99,6 @@ def _s3_credentials_from_env(bucket_prefix):
|
||||
|
||||
|
||||
class Development(Config):
|
||||
BASIC_AUTH_FORCE = False
|
||||
DEBUG = True
|
||||
SESSION_COOKIE_SECURE = False
|
||||
SESSION_PROTECTION = None
|
||||
@@ -138,7 +135,6 @@ class Test(Development):
|
||||
class Production(Config):
|
||||
HEADER_COLOUR = "#005EA5" # $govuk-blue
|
||||
HTTP_PROTOCOL = "https"
|
||||
BASIC_AUTH_FORCE = True
|
||||
ASSET_DOMAIN = "" # TODO use a CDN
|
||||
ASSET_PATH = "/static/" # TODO use a CDN
|
||||
DEBUG = False
|
||||
@@ -153,7 +149,6 @@ class Production(Config):
|
||||
|
||||
|
||||
class Staging(Production):
|
||||
BASIC_AUTH_FORCE = True
|
||||
HEADER_COLOUR = "#00ff00" # $green
|
||||
|
||||
|
||||
@@ -166,7 +161,6 @@ class Sandbox(Staging):
|
||||
|
||||
|
||||
class Scanning(Production):
|
||||
BASIC_AUTH_FORCE = False
|
||||
HTTP_PROTOCOL = "http"
|
||||
API_HOST_NAME = "https://notify-api-staging.app.cloud.gov/"
|
||||
SECRET_KEY = "dev-notify-secret-key" # nosec B105 - only used in development
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
from flask import jsonify, request
|
||||
from flask_basicauth import BasicAuth
|
||||
|
||||
|
||||
class CustomBasicAuth(BasicAuth):
|
||||
"""
|
||||
Description:
|
||||
Override BasicAuth to permit anonymous healthcheck at /_status?simple=true
|
||||
"""
|
||||
|
||||
def challenge(self):
|
||||
if "/_status" in request.url:
|
||||
if request.args.get("elb", None) or request.args.get("simple", None):
|
||||
return jsonify(status="ok"), 200
|
||||
return super(CustomBasicAuth, self).challenge()
|
||||
|
||||
|
||||
custom_basic_auth = CustomBasicAuth()
|
||||
@@ -45,10 +45,11 @@ def _create_example_template(service_id):
|
||||
@user_is_gov_user
|
||||
def add_service():
|
||||
default_organization_type = current_user.default_organization_type
|
||||
if default_organization_type is None:
|
||||
default_organization_type = "federal"
|
||||
form = CreateServiceForm(
|
||||
# avoid setting a default for now; the US gov email addresses aren't as useful as the UK
|
||||
# ones for guessing the org type
|
||||
organization_type=None
|
||||
# This value is currently not useful but if it is not set it will result in a bug
|
||||
organization_type=default_organization_type
|
||||
)
|
||||
|
||||
if form.validate_on_submit():
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import os
|
||||
|
||||
from flask import (
|
||||
Markup,
|
||||
abort,
|
||||
@@ -10,9 +12,10 @@ from flask import (
|
||||
)
|
||||
from flask_login import current_user
|
||||
|
||||
from app import login_manager
|
||||
from app import login_manager, user_api_client
|
||||
from app.main import main
|
||||
from app.main.forms import LoginForm
|
||||
from app.main.views.verify import activate_user
|
||||
from app.models.user import InvitedUser, User
|
||||
from app.utils import hide_from_search_engines
|
||||
from app.utils.login import is_safe_redirect_url
|
||||
@@ -22,6 +25,12 @@ from app.utils.login import is_safe_redirect_url
|
||||
@hide_from_search_engines
|
||||
def sign_in():
|
||||
redirect_url = request.args.get("next")
|
||||
|
||||
if os.getenv("NOTIFY_E2E_TEST_EMAIL"):
|
||||
user = user_api_client.get_user_by_email(os.getenv("NOTIFY_E2E_TEST_EMAIL"))
|
||||
activate_user(user["id"])
|
||||
return redirect(url_for("main.show_accounts_or_dashboard", next=redirect_url))
|
||||
|
||||
if current_user and current_user.is_authenticated:
|
||||
if redirect_url and is_safe_redirect_url(redirect_url):
|
||||
return redirect(redirect_url)
|
||||
@@ -58,6 +67,7 @@ def sign_in():
|
||||
|
||||
if user.sms_auth:
|
||||
return redirect(url_for(".two_factor_sms", next=redirect_url))
|
||||
|
||||
if user.email_auth:
|
||||
return redirect(
|
||||
url_for(".two_factor_email_sent", next=redirect_url)
|
||||
|
||||
@@ -3,23 +3,15 @@
|
||||
|
||||
{% block headIcons %}
|
||||
<link rel="shortcut icon" sizes="16x16 32x32 48x48" href="{{ asset_url('images/favicon.ico') }}" type="image/x-icon" />
|
||||
<link rel="mask-icon" href="{{ asset_url('images/govuk-mask-icon.svg') }}" color="{{ themeColor | default('#0b0c0c') }}"> {# Hardcoded value of $govuk-black #}
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ asset_url('images/govuk-apple-touch-icon-180x180.png') }}">
|
||||
<link rel="apple-touch-icon" sizes="167x167" href="{{ asset_url('images/govuk-apple-touch-icon-167x167.png') }}">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="{{ asset_url('images/govuk-apple-touch-icon-152x152.png') }}">
|
||||
<link rel="apple-touch-icon" href="{{ asset_url('images/govuk-apple-touch-icon.png') }}">
|
||||
<link rel="mask-icon" href="{{ asset_url('images/usa-mask-icon.svg') }}" color="{{ themeColor | default('#F0F0F0') }}">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ asset_url('images/apple-touch-icon.png') }}">
|
||||
<link rel="apple-touch-icon" href="{{ asset_url('images/apple-touch-icon.png') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
{%- for font in font_paths %}
|
||||
<link rel="preload" href="{{ asset_url(font, with_querystring_hash=False) }}" as="font" type="font/woff2" crossorigin>
|
||||
{%- endfor %}
|
||||
<link rel="stylesheet" media="screen" href="{{ asset_url('css/styles.css') }}" />
|
||||
{% block extra_stylesheets %}
|
||||
{% endblock %}
|
||||
<style nonce="{{ csp_nonce() }}">
|
||||
.govuk-header__container { border-color: {{header_colour}} }
|
||||
</style>
|
||||
{% if g.hide_from_search_engines %}
|
||||
<meta name="robots" content="noindex" />
|
||||
{% endif %}
|
||||
@@ -28,6 +20,8 @@
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
{% endblock %}
|
||||
{% block meta %}
|
||||
<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> -->
|
||||
{% endblock %}
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<span class="big-number-with-status">
|
||||
{{ big_number(number, label, link=link, smaller=smaller, smallest=smallest) }}
|
||||
{% if show_failures %}
|
||||
<span class="big-number-status{% if danger_zone %}-failing{% endif %}">
|
||||
<span class="big-number-status{% if danger_zone %} big-number-status--failing{% endif %}">
|
||||
{% if failures %}
|
||||
{% if failure_link %}
|
||||
<a class="usa-link" href="{{ failure_link }}">
|
||||
|
||||
@@ -55,7 +55,9 @@
|
||||
<a href="/" title="notify.gov">notify.gov</a>
|
||||
</em>
|
||||
</div>
|
||||
<button type="button" class="usa-menu-btn">Menu</button>
|
||||
{% if current_user.is_authenticated %}
|
||||
<button type="button" class="usa-menu-btn">Menu</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
<nav aria-label="Primary navigation" class="usa-nav">
|
||||
<div class="usa-nav__inner">
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
link_current_item=False,
|
||||
root_element='h1'
|
||||
) %}
|
||||
<{{ root_element }} class="font-body-lg folder-heading"{% if root_element == 'h1' %} id="page-header"{% endif %}>
|
||||
<{{ root_element }} class="font-body-lg folder-heading margin-bottom-0"{% if root_element == 'h1' %} id="page-header"{% endif %}>
|
||||
{% for folder in folders %}
|
||||
{% if loop.last and not link_current_item %}
|
||||
{% if folder.template_type or not folder.id %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% macro status_box(number, label, failing=false, percentage=None, url=None) %}
|
||||
<div class="big-number-with-status">
|
||||
<div class="big-number-status{% if failing %}-failing{% endif %}">
|
||||
<div class="big-number-status{% if failing %} big-number-status--failing{% endif %}">
|
||||
{% if url %}
|
||||
<a class="usa-link" href="{{ url }}">{{ number }} {{ label }}</a>
|
||||
{% else %}
|
||||
|
||||
@@ -20,17 +20,17 @@
|
||||
|
||||
{% block headIcons %}
|
||||
<link rel="shortcut icon" sizes="16x16 32x32 48x48" href="{{ assetPath | default('/assets') }}/images/favicon.ico" type="image/x-icon" />
|
||||
<link rel="mask-icon" href="{{ assetPath | default('/assets') }}/images/govuk-mask-icon.svg" color="{{ themeColor | default('#0b0c0c') }}"> {# Hardcoded value of $govuk-black #}
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ assetPath | default('/assets') }}/images/govuk-apple-touch-icon-180x180.png">
|
||||
<link rel="apple-touch-icon" sizes="167x167" href="{{ assetPath | default('/assets') }}/images/govuk-apple-touch-icon-167x167.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="{{ assetPath | default('/assets') }}/images/govuk-apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" href="{{ assetPath | default('/assets') }}/images/govuk-apple-touch-icon.png">
|
||||
<link rel="mask-icon" href="{{ assetPath | default('/assets') }}/images/usa-mask-icon.svg" color="{{ themeColor | default('#F0F0F0') }}">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ assetPath | default('/assets') }}/images/apple-touch-icon.png">
|
||||
<link rel="apple-touch-icon" href="{{ assetPath | default('/assets') }}/images/apple-touch-icon.png">
|
||||
{% endblock %}
|
||||
|
||||
{% block head %}{% endblock %}
|
||||
{# The default og:image is added below head so that scrapers see any custom metatags first, and this is just a fallback #}
|
||||
{# image url needs to be absolute e.g. http://wwww.domain.com/.../govuk-opengraph-image.png #}
|
||||
<!-- <meta property="og:image" content="{{ assetUrl | default('/assets') }}/images/govuk-opengraph-image.png"> -->
|
||||
{% block meta %}
|
||||
<meta property="og:site_name" content="Notify.gov">
|
||||
<meta property="og:image" content="{{ asset_url('images/usa-opengraph-image.png') }}">
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body class="usa-template__body {{ bodyClasses }}">
|
||||
<script nonce="{{ csp_nonce() }}">document.body.className = ((document.body.className) ? document.body.className + ' js-enabled' : 'js-enabled');</script>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<div class="ajax-block-container">
|
||||
{% if notifications_deleted %}
|
||||
<div class="grid-row bottom-gutter-1-2">
|
||||
<div class="grid-row ">
|
||||
{% for label, query_param, url, count in counts %}
|
||||
{% if query_param == 'pending' %}
|
||||
<div class="grid-col-3">{{ big_number(count, query_param, smaller=True) }}</div>
|
||||
@@ -14,7 +14,7 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="bottom-gutter">
|
||||
<div class="tabs">
|
||||
{{ pill(counts, request.args.get('status', '')) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
|
||||
{{ form.name(param_extensions={"hint": {"text": "You can change this later"}}) }}
|
||||
|
||||
{% if not default_organization_type %}
|
||||
<!--{% if not default_organization_type %}
|
||||
{{ form.organization_type }}
|
||||
{% endif %}
|
||||
{% endif %}-->
|
||||
|
||||
{{ page_footer('Add service') }}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
API integration
|
||||
</h1>
|
||||
|
||||
<nav class="grid-row bottom-gutter-1-2">
|
||||
<nav class="grid-row">
|
||||
<div class="grid-col-4">
|
||||
<a class="usa-link pill-separate-item" href="{{ url_for('.api_keys', service_id=current_service.id) }}">API keys</a>
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
{% block maincolumn_content %}
|
||||
|
||||
<div class="bottom-gutter-1-2">
|
||||
<div class="">
|
||||
{% call banner_wrapper(type='dangerous') %}
|
||||
|
||||
{% if recipients.too_many_rows %}
|
||||
|
||||
@@ -21,11 +21,6 @@
|
||||
|
||||
{{ page_header('Preview of {}'.format(template.name)) }}
|
||||
|
||||
{{ usaSkipLink({
|
||||
"text": "Skip to file contents",
|
||||
"href": "#" + file_contents_header_id
|
||||
}) }}
|
||||
|
||||
{{ template|string }}
|
||||
<div class="bottom-gutter-3-2">
|
||||
<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'>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
{% from "components/table.html" import mapping_table, row, field, text_field, index_field, hidden_field_heading %}
|
||||
{% from "components/file-upload.html" import file_upload %}
|
||||
{% from "components/components/back-link/macro.njk" import usaBackLink %}
|
||||
{% from "components/components/alert/macro.njk" import usaAlert %}
|
||||
|
||||
{% block service_page_title %}
|
||||
Error
|
||||
@@ -15,27 +16,31 @@
|
||||
|
||||
{% block maincolumn_content %}
|
||||
|
||||
<div class="bottom-gutter-1-2">
|
||||
<div class="">
|
||||
{% call banner_wrapper(type='dangerous') %}
|
||||
{% if row_errors|length == 1 %}
|
||||
<h1 class='banner-title' data-module="track-error" data-error-type="Bad rows" data-error-label="{{ upload_id }}">
|
||||
There’s a problem with {{ original_file_name }}
|
||||
</h1>
|
||||
<p>
|
||||
You need to {{ row_errors[0] }}.
|
||||
</p>
|
||||
<div class="usa-alert usa-alert--error" role="alert">
|
||||
<div class="usa-alert__body">
|
||||
<h1 class="usa-alert__heading">There’s a problem with {{ original_file_name }}</h1>
|
||||
<p class="usa-alert__text">
|
||||
You need to {{ row_errors[0] }}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<h1 class='banner-title' data-module="track-error" data-error-type="Bad rows" data-error-label="{{ upload_id }}">
|
||||
There are some problems with {{ original_file_name }}
|
||||
</h1>
|
||||
<p>
|
||||
You need to:
|
||||
</p>
|
||||
<ul class="list-bullet">
|
||||
{% for error in row_errors %}
|
||||
<li>{{ error }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div class="usa-alert usa-alert--error" role="alert">
|
||||
<div class="usa-alert__body">
|
||||
<h1 class="usa-alert__heading">There’s a problem with {{ original_file_name }}</h1>
|
||||
<p class="usa-alert__text">
|
||||
You need to:
|
||||
<ul class="list-bullet">
|
||||
{% for error in row_errors %}
|
||||
<li>{{ error }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
</div>
|
||||
@@ -49,7 +54,6 @@
|
||||
button_text='Upload your file again'
|
||||
) }}
|
||||
</div>
|
||||
<a href="#content" class="usa-link back-to-top-link">Back to top</a>
|
||||
</div>
|
||||
|
||||
<div class="fullscreen-content" data-module="fullscreen-table">
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
|
||||
<div class="ajax-block-container">
|
||||
{% if current_service.scheduled_job_stats.count %}
|
||||
<h2 class="heading-medium heading-upcoming-jobs">
|
||||
<h2 class="font-body-lg margin-y-0">
|
||||
In the next few days
|
||||
</h2>
|
||||
<a class="usa-link banner-dashboard" href="{{ url_for('.uploads', service_id=current_service.id) }}">
|
||||
<a class="usa-link banner-dashboard margin-bottom-2 display-block" href="{{ url_for('.uploads', service_id=current_service.id) }}">
|
||||
<span class="banner-dashboard-count">
|
||||
{{ current_service.scheduled_job_stats.count }}
|
||||
</span>
|
||||
@@ -18,7 +18,7 @@
|
||||
{% endif %}
|
||||
</span>
|
||||
<span class="banner-dashboard-meta">
|
||||
sending starts
|
||||
- sending starts
|
||||
{{ current_service.scheduled_job_stats.soonest_scheduled_for|format_datetime_relative }}
|
||||
</span>
|
||||
</a>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
{{ ajax_block(partials, updates_url, 'upcoming') }}
|
||||
|
||||
<h2 class="font-body-lg margin-top-0">
|
||||
<h2 class="font-body-lg margin-top-0 margin-bottom-1">
|
||||
In the last seven days
|
||||
</h2>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
{{ ajax_block(partials, updates_url, 'template-statistics') }}
|
||||
|
||||
{% if current_user.has_permissions('manage_service') %}
|
||||
<h2 class='font-body-lg'>This year</h2>
|
||||
<h2 class='font-body-lg margin-bottom-0'>This year</h2>
|
||||
{{ ajax_block(partials, updates_url, 'usage') }}
|
||||
{{ show_more(
|
||||
url_for(".usage", service_id=current_service['id']),
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
caption_visible=False
|
||||
) %}
|
||||
{% for message_status, description in [
|
||||
('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.'),
|
||||
('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. Notify is waiting for delivery information.'),
|
||||
('Sent', 'The mobile networks may not provide any more delivery information.'),
|
||||
('Delivered', 'The message was successfully delivered. Notify cannot tell you if a user has opened or read a message.'),
|
||||
('Not delivered', ('The provider could not deliver the message. This can happen if the phone number was wrong or if the network operator rejects the message. If you’re sure that these phone numbers are correct, you should <a class="usa-link" href="' + url_for(".support") + '">contact us</a>. If not, you should remove them from your database. You’ll still be charged for text messages that cannot be delivered.')|safe),
|
||||
|
||||
@@ -20,7 +20,11 @@ data={
|
||||
) }}
|
||||
|
||||
<p>During pilot period, each service has an allowance of 250,000 free text messages. Once this allowance is met, the
|
||||
application will stop delivering messages. There’s no monthly charge, no setup fee and no procurement cost.</p>
|
||||
application will stop delivering messages. There's no monthly charge, no setup fee and no procurement cost.</p>
|
||||
<p>When a new service is added, it will start in <a class="usa-link" href="{{ url_for('main.trial_mode_new') }}">trial mode</a>. Moving a service out of trial mode is subject to approval by
|
||||
the Notify.gov team.</p>
|
||||
<p>You'll use more messages towards the allowance if you send text messages longer than 160 characters.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{% if not current_user.is_authenticated %}
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
{{ form.placeholder_value(param_extensions={"classes": ""}) }}
|
||||
</div>
|
||||
{% if skip_link or link_to_upload %}
|
||||
<div class="grid-col-12">
|
||||
<div class="grid-col-12 margin-top-1">
|
||||
{% if link_to_upload %}
|
||||
<a class="usa-link" 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-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>
|
||||
{% endif %}
|
||||
{% if skip_link %}
|
||||
<a href="{{ skip_link[1] }}" class="usa-link">{{ skip_link[0] }}</a>
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<a class="usa-link" href="{{ url_for('.get_example_csv', service_id=current_service.id, template_id=template.id) }}" download>Download this example (<abbr title="Comma separated values">CSV</abbr>)</a>
|
||||
</p>
|
||||
|
||||
<h2 class="font-body-lg">Your file will populate this template ({{ template.name }})</h2>
|
||||
<h2 class="font-body-lg margin-bottom-1">Your file will populate this template:<br><span class="font-body-lg">({{ template.name }})</span></h2>
|
||||
{{ template|string }}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -373,7 +373,7 @@
|
||||
{% endif %}
|
||||
{% if (not current_service.active) and current_user.platform_admin %}
|
||||
<p>
|
||||
<div class="hint bottom-gutter-1-2">
|
||||
<div class="hint ">
|
||||
Service suspended
|
||||
</div>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
{% block maincolumn_content %}
|
||||
|
||||
<div class="bottom-gutter-1-2">
|
||||
<div class="">
|
||||
<h1 class="font-body-2xl margin-bottom-3">Choose a template</h1>
|
||||
{{ folder_path(template_folder_path, current_service.id, template_type, current_user, root_element='h2') }}
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
{% block maincolumn_content %}
|
||||
|
||||
<div class="bottom-gutter-1-2">
|
||||
<div class="">
|
||||
<h1 class="font-body-2xl margin-bottom-3">{{ page_title }}</h1>
|
||||
{{ copy_folder_path(template_folder_path, current_service.id, from_service, current_user) }}
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
{% block maincolumn_content %}
|
||||
|
||||
<div class="grid-row bottom-gutter-1-2">
|
||||
<div class="grid-row ">
|
||||
<div class="grid-col-12">
|
||||
{{ folder_path(
|
||||
folders=template_folder_path,
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
{% else %}
|
||||
<div class="grid-row">
|
||||
<div class="grid-col-12">
|
||||
<h1 class="font-body-lg folder-heading">
|
||||
<h1 class="font-body-xl folder-heading margin-top-0">
|
||||
Review your message
|
||||
</h1>
|
||||
{{ folder_path(
|
||||
@@ -70,7 +70,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!--<div class="bottom-gutter-1-2">
|
||||
<!--<div class="">
|
||||
{{ copy_to_clipboard(template.id, name="Template ID", thing='template ID') }}
|
||||
</div>-->
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from flask import current_app
|
||||
from notifications_utils.recipients import RecipientCSV
|
||||
|
||||
from app.models.spreadsheet import Spreadsheet
|
||||
@@ -75,7 +76,7 @@ def generate_notifications_csv(**kwargs):
|
||||
fieldnames = (
|
||||
["Row number"]
|
||||
+ original_column_headers
|
||||
+ ["Template", "Type", "Job", "Status", "Time"]
|
||||
+ ["Template", "Type", "Sent by", "Job", "Status", "Time"]
|
||||
)
|
||||
else:
|
||||
fieldnames = [
|
||||
@@ -95,6 +96,7 @@ def generate_notifications_csv(**kwargs):
|
||||
**kwargs
|
||||
)
|
||||
for notification in notifications_resp["notifications"]:
|
||||
current_app.logger.info(notification)
|
||||
if kwargs.get("job_id"):
|
||||
values = (
|
||||
[
|
||||
@@ -107,6 +109,7 @@ def generate_notifications_csv(**kwargs):
|
||||
+ [
|
||||
notification["template_name"],
|
||||
notification["template_type"],
|
||||
notification["created_by_name"],
|
||||
notification["job_name"],
|
||||
notification["status"],
|
||||
notification["created_at"],
|
||||
|
||||