Merge branch 'main' of https://github.com/GSA/notifications-admin into 1676-individual-job-table-updates

# Conflicts:
#	app/templates/partials/jobs/notifications.html
This commit is contained in:
Jonathan Bobel
2024-07-29 15:55:59 -04:00
33 changed files with 305 additions and 209 deletions

View File

@@ -407,16 +407,6 @@
"is_secret": false
}
],
"app/main/views/sign_in.py": [
{
"type": "Private Key",
"filename": "app/main/views/sign_in.py",
"hashed_secret": "1348b145fa1a555461c1b790a2f66614781091e9",
"is_verified": false,
"line_number": 27,
"is_secret": false
}
],
"app/templates/new/components/head.html": [
{
"type": "Base64 High Entropy String",
@@ -702,5 +692,5 @@
}
]
},
"generated_at": "2024-07-11T16:37:23Z"
"generated_at": "2024-07-24T14:13:02Z"
}

View File

@@ -327,6 +327,16 @@ td.table-empty-message {
bottom: 0;
}
@media (max-width: units('desktop-lg')) {
.table-overflow-x-auto {
overflow-x: auto;
table {
min-width: 768px;
}
}
}
// Dashboard
.dashboard {
@@ -376,9 +386,6 @@ td.table-empty-message {
background-image: url(../img/material-icons/description.svg);
}
}
.table-wrapper {
overflow-x: scroll;
}
}
.dashboard-table {

View File

@@ -230,7 +230,12 @@ def set_up_your_profile():
debug_msg(
f"Added user {usr.email_address} to service {invite_data['service_id']}"
)
return redirect(url_for("main.show_accounts_or_dashboard"))
# notify-admin-1766
# redirect new users to templates area of new service instead of dashboard
service_id = invite_data["service_id"]
url = url_for(".service_dashboard", service_id=service_id)
url = f"{url}/templates"
return redirect(url)
elif login_gov_error:
current_app.logger.error(f"login.gov error: {login_gov_error}")

View File

@@ -29,12 +29,18 @@ from notifications_utils.url_safe_token import generate_token
def _reformat_keystring(orig):
new_keystring = orig.replace("-----BEGIN PRIVATE KEY-----", "")
new_keystring = new_keystring.replace("-----END PRIVATE KEY-----", "")
private_key = "PRIVATE " # pragma: allowlist secret
private_key = f"{private_key} KEY"
new_keystring = orig.replace(f"-----BEGIN {private_key}-----", "")
new_keystring = new_keystring.replace(f"-----END {private_key}-----", "")
new_keystring = new_keystring.strip()
new_keystring = new_keystring.replace(" ", "\n")
new_keystring = "\n".join(
["-----BEGIN PRIVATE KEY-----", new_keystring, "-----END PRIVATE KEY-----"]
[
f"-----BEGIN {private_key}-----",
new_keystring,
f"-----END {private_key}-----",
]
)
new_keystring = f"{new_keystring}\n"
return new_keystring
@@ -65,7 +71,9 @@ def _get_access_token(code, state):
response = requests.post(url, headers=headers)
if response.json().get("access_token") is None:
# Capture the response json here so it hopefully shows up in error reports
current_app.logger.error(f"Error when getting access token {response.json()}")
current_app.logger.error(
f"Error when getting access token {response.json()} #notify-admin-1505"
)
raise KeyError(f"'access_token' {response.json()}")
access_token = response.json()["access_token"]
return access_token
@@ -90,7 +98,9 @@ def _do_login_dot_gov():
login_gov_error = request.args.get("error")
if login_gov_error:
current_app.logger.error(f"login.gov error: {login_gov_error}")
current_app.logger.error(
f"login.gov error: {login_gov_error} #notify-admin-1505"
)
raise Exception(f"Could not login with login.gov {login_gov_error}")
elif code and state:
@@ -100,12 +110,15 @@ def _do_login_dot_gov():
user_email, user_uuid = _get_user_email_and_uuid(access_token)
if not is_gov_user(user_email):
current_app.logger.error(
"invited user has a non-government email address."
"invited user has a non-government email address. #notify-admin-1505"
)
flash("You must use a government email address.")
abort(403)
redirect_url = request.args.get("next")
user = user_api_client.get_user_by_uuid_or_email(user_uuid, user_email)
current_app.logger.info(
f"Retrieved user {user['id']} from db #notify-admin-1505"
)
# Check if the email needs to be revalidated
is_fresh_email = is_less_than_days_ago(
@@ -115,9 +128,10 @@ def _do_login_dot_gov():
return verify_email(user, redirect_url)
usr = User.from_email_address(user["email_address"])
current_app.logger.info(f"activating user {usr.id} #notify-admin-1505")
activate_user(usr.id)
except BaseException as be: # noqa B036
current_app.logger.error(be)
current_app.logger.error(f"Error signing in: {be} #notify-admin-1505 ")
error(401)
return redirect(url_for("main.show_accounts_or_dashboard", next=redirect_url))

View File

@@ -38,6 +38,7 @@ def verify_email(token):
current_app.config["EMAIL_EXPIRY_SECONDS"],
)
except SignatureExpired:
current_app.logger.error("Email link expired #notify-admin-1505")
flash(
"The link in the email we sent you has expired. We've sent you a new one."
)
@@ -50,6 +51,9 @@ def verify_email(token):
abort(404)
if user.is_active:
current_app.logger.error(
f"User is using an invite link but is already logged in {user.id} #notify-admin-1505"
)
flash("That verification link has expired.")
return redirect(url_for("main.sign_in"))
@@ -59,6 +63,7 @@ def verify_email(token):
user.send_verify_code()
session["user_details"] = {"email": user.email_address, "id": user.id}
current_app.logger.info(f"Email verified for user {user.id} #notify-admin-1505")
return redirect(url_for("main.verify"))
@@ -78,5 +83,7 @@ def activate_user(user_id):
return redirect(url_for("main.organization_dashboard", org_id=organization_id))
else:
activated_user = user.activate()
current_app.logger.info(f"Activated user {user.id} #notify-admin-1505")
activated_user.login()
current_app.logger.info(f"Logged in user {user.id} #notify-admin-1505")
return redirect(url_for("main.add_service", first="first"))

View File

@@ -22,7 +22,7 @@
{% else %}
{% if notifications %}
<div class="dashboard-table job-status-table">
<div class="dashboard-table job-status-table table-overflow-x-auto">
{% endif %}
{% if job.still_processing %}
<p class="bottom-gutter hint">

View File

@@ -1,8 +1,8 @@
{% from "components/table.html" import list_table, field, right_aligned_field_heading, row_heading, notification_status_field %}
{% from "components/page-footer.html" import page_footer %}
<div class="ajax-block-container table-wrapper" aria-labelledby='pill-selected-item'>
<div class="dashboard-table bottom-gutter-3-2">
<div class="ajax-block-container" aria-labelledby='pill-selected-item'>
<div class="dashboard-table table-overflow-x-auto">
{% call(item, row_number) list_table(
[notification],

View File

@@ -5,7 +5,7 @@
<div class="ajax-block-container" id='pill-selected-item'>
{% if notifications %}
<div class="table-wrapper">
<div class="table-overflow-x-auto">
<div class='dashboard-table'>
{% endif %}
{% call(item, row_number) list_table(

View File

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

View File

@@ -41,7 +41,7 @@
</li>
</ul>
</div>
<div class="usa-table-container--scrollable" tabindex="0">
<div class="usa-table-container--scrollable table-overflow-x-auto" tabindex="0">
<table class="usa-table usa-table--borderless width-full">
<caption class="font-body-lg table-heading">
Note: Only the first 5 rows are displayed here.

View File

@@ -1,6 +1,6 @@
{% from "components/table.html" import list_table, field, right_aligned_field_heading, row_heading %}
<div class="table-wrapper">
<div class="table-overflow-x-auto">
<div class='dashboard-table ajax-block-container'>
{% call(item, row_number) list_table(
jobs,

View File

@@ -28,7 +28,7 @@
No messages sent
</p>
{% else %}
<div class='template-statistics-table'>
<div class='template-statistics-table table-overflow-x-auto'>
{% call(item, row_number) list_table(
month.templates_used,
caption=month.name,

View File

@@ -30,7 +30,7 @@
{{ ajax_block(partials, updates_url, 'template-statistics') }}
<h2 class="margin-top-4 margin-bottom-1">Recent Batches</h2>
<div class="table-wrapper">
<div class="table-overflow-x-auto">
<table class="usa-table usa-table--borderless job-table">
<thead class="table-field-headings">
<tr>

View File

@@ -2,7 +2,7 @@
<div class="ajax-block-container">
{% if template_statistics|length > 1 %}
<div class='template-statistics-table'>
<div class='template-statistics-table table-overflow-x-auto'>
{% call(item, row_number) list_table(
template_statistics,
caption="Messages sent by template",

View File

@@ -24,6 +24,10 @@
<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>
<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>
<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('.guidance_index', _anchor='personalized-content') }}">how to personalize your content</a>.</p>
@@ -44,7 +48,6 @@
<p class="usa-body">Notify lets you:</p>
<ul class="list list-bullet">
<li>set different permission levels for each team member</li>
<li>invite team members who do not have a government email address</li>
<li>choose who else can manage team members</li>
</ul>

View File

@@ -162,55 +162,57 @@
location, the flag to receive the content needs to be captured in its own column with a Yes or No (Y/N) flag.</p>
<h3>Example</h3>
<table class="usa-table">
<caption class="usa-sr-only">
Example
</caption>
<thead>
<tr>
<th scope="col">Phone number</th>
<th scope="col">First name</th>
<th scope="col">Last name</th>
<th scope="col">Spanish</th>
<th scope="col">English</th>
<th scope="col">Date</th>
<th scope="col">Time</th>
<th scope="col">Location</th>
</tr>
</thead>
<tbody>
<tr>
<td>123-456-7890</td>
<td>Lulu</td>
<td>Praether</td>
<td>N</td>
<td>Y</td>
<td>November 2, 2023</td>
<td>3:25</td>
<td>123 Ford Rd.</td>
</tr>
<tr>
<td>234-567-8901</td>
<td>Sela</td>
<td>Appel</td>
<td>Y</td>
<td>N</td>
<td>November 2, 2023</td>
<td>4:00</td>
<td>123 Ford Rd.</td>
</tr>
<tr>
<td>123-456-7890</td>
<td>Dexter</td>
<td>Moseley</td>
<td>N</td>
<td>Y</td>
<td>November 2, 2023</td>
<td>2:00</td>
<td>123 Ford Rd.</td>
</tr>
</tbody>
</table>
<div class="table-overflow-x-auto">
<table class="usa-table">
<caption class="usa-sr-only">
Example
</caption>
<thead>
<tr>
<th scope="col">Phone number</th>
<th scope="col">First name</th>
<th scope="col">Last name</th>
<th scope="col">Spanish</th>
<th scope="col">English</th>
<th scope="col">Date</th>
<th scope="col">Time</th>
<th scope="col">Location</th>
</tr>
</thead>
<tbody>
<tr>
<td>123-456-7890</td>
<td>Lulu</td>
<td>Praether</td>
<td>N</td>
<td>Y</td>
<td>November 2, 2023</td>
<td>3:25</td>
<td>123 Ford Rd.</td>
</tr>
<tr>
<td>234-567-8901</td>
<td>Sela</td>
<td>Appel</td>
<td>Y</td>
<td>N</td>
<td>November 2, 2023</td>
<td>4:00</td>
<td>123 Ford Rd.</td>
</tr>
<tr>
<td>123-456-7890</td>
<td>Dexter</td>
<td>Moseley</td>
<td>N</td>
<td>Y</td>
<td>November 2, 2023</td>
<td>2:00</td>
<td>123 Ford Rd.</td>
</tr>
</tbody>
</table>
</div>
{# Preventing fraud #}
<h2 class="padding-top-1" id="prevent-fraud">Preventing fraud</h2>

View File

@@ -23,36 +23,34 @@ Inbound SMS
<h1 class="font-body-2xl">
Inbound SMS
</h1>
<table class="usa-table usa-table--borderless inbound">
<thread>
<tr>
<th>{{table_headings.field_headings[0]}}</th>
<th>{{table_headings.field_headings[1]}}</th>
<th>{{table_headings.field_headings[2]}}</th>
</tr>
</thread>
<tbody>
{% for value in inbound_num_list.data: %}
<div class="table-overflow-x-auto">
<table class="usa-table usa-table--borderless inbound width-full">
<thead>
<tr>
<td>{{value.number}}</td>
<td>
{% if value.active %}
Active
{% elif not value.service.name %}
Not used
{% else %}
Inactive
{% endif %}
</td>
<td>
<a href="{{ url_for('main.service_dashboard', service_id=value.service.id) }}" class="usa-link bold">{{ value.service.name }}</a>
</td>
<th>{{table_headings.field_headings[0]}}</th>
<th>{{table_headings.field_headings[1]}}</th>
<th>{{table_headings.field_headings[2]}}</th>
</tr>
{% endfor %}
</tbody>
</table>
</thead>
<tbody>
{% for value in inbound_num_list.data: %}
<tr>
<td>{{value.number}}</td>
<td>
{% if value.active %}
Active
{% elif not value.service.name %}
Not used
{% else %}
Inactive
{% endif %}
</td>
<td>
<a href="{{ url_for('main.service_dashboard', service_id=value.service.id) }}" class="usa-link bold">{{ value.service.name }}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

View File

@@ -15,7 +15,7 @@
{% block maincolumn_content %}
{{ page_header('Invite {}'.format(user_to_invite.name if user_to_invite else 'a team member')) }}
<a href="#permissions">Learn more about user permissions.</a>
{% call form_wrapper() %}
{% if user_to_invite %}
@@ -36,5 +36,99 @@
{{ page_footer('Send invitation email') }}
{% endcall %}
<h2 id="permissions">Set up user permissions</h2>
<p>Setting the right digital control is one of many aspects to keep content and information on a need to know basis. Permissions allow you to do this. Give team members access to important views related to their responsibilities.</p>
<h3 class="site-preview-heading">Permissions</h3>
<div class="usa-accordion usa-accordion--bordered margin-top-1">
<h4 class="usa-accordion__heading">
<button
type="button"
class="usa-accordion__button"
aria-expanded="true"
aria-controls="b-a1"
>
See dashboard
</button>
</h4>
<div id="b-a1" class="usa-accordion__content usa-prose">
<p>Allows users to view the dashboard but not have access to any other functions on the site.
Dashboard viewers can see: Weekly message quantity</p>
<ul>
<li>Message templates used</li>
<li>Recent batches of sent messages</li>
</ul>
<p>This also gives access to:</p>
<ul>
<li>List of templates used by month</li>
<li>Batch details with message status</li>
</ul>
</div>
<h4 class="usa-accordion__heading">
<button
type="button"
class="usa-accordion__button"
aria-expanded="false"
aria-controls="b-a2"
>
Send messages
</button>
</h4>
<div id="b-a2" class="usa-accordion__content usa-prose">
<p>
Allows users to view, select and send approved messages, but restricts users from editing templates
and/or folders. Team members responsible for sending message batches can use templates to prepare
and schedule texts. Actions they take in this section:
</p>
<ul>
<li>View and use templates</li>
<li>Enter personalized message field content</li>
<li>Schedule messages for sending</li>
<li>Send messages</li>
</ul>
</div>
<h4 class="usa-accordion__heading">
<button
type="button"
class="usa-accordion__button"
aria-expanded="false"
aria-controls="b-a3"
>
Add and edit templates
</button>
</h4>
<div id="b-a3" class="usa-accordion__content usa-prose">
<p>
Allows users to view, create or edit, and more or delete templates and folders. They will set up real
messages, but are restricted from uploading data or sending or seeing previous versions. Some actions
they can take:
</p>
<ul>
<li>Create a new template</li>
<li>Create a new folder</li>
<li>Move (or organize) folders and templates</li>
<li>Delete templates and/or folders</li>
</ul>
</div>
<h4 class="usa-accordion__heading">
<button
type="button"
class="usa-accordion__button"
aria-expanded="false"
aria-controls="b-a4"
>
Manage settings and team
</button>
</h4>
<div id="b-a4" class="usa-accordion__content usa-prose">
<p>Leads with service management responsibility may do so in Settings. Managed within Settings:</p>
<ul>
<li>Change service name</li>
<li>Invite team members</li>
<li>Remove unnecessary team members</li>
<li>Turn off the ability to send text messages</li>
<li>Turn off the ability to send service name with text message</li>
</ul>
</div>
</div>
{% endblock %}

View File

@@ -49,7 +49,7 @@
<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>
<div class="margin-bottom-8">
<div class="margin-bottom-8 table-overflow-x-auto">
{% call mapping_table(
caption='Message statuses text messages',
field_headings=['Status', 'Description'],

View File

@@ -44,33 +44,31 @@
</div>
</div>
<div class="table-wrapper">
<div class="dashboard-table">
{% call(item, row_number) list_table(
notifications_by_type|reverse,
caption='Messages sent since May 2023',
caption_visible=False,
field_headings=[
'Date',
99|message_count_noun('email')|capitalize,
99|message_count_noun('sms')|capitalize,
],
empty_message='No data to show'
) %}
{% call field() %}
{{ item.date | format_date_normal }}
{% endcall %}
{% call field() %}
{{ item.emails|format_thousands }}
{% endcall %}
{% call field() %}
{{ item.sms|format_thousands }}
{% endcall %}
<div class="dashboard-table table-overflow-x-auto">
{% call(item, row_number) list_table(
notifications_by_type|reverse,
caption='Messages sent since May 2023',
caption_visible=False,
field_headings=[
'Date',
99|message_count_noun('email')|capitalize,
99|message_count_noun('sms')|capitalize,
],
empty_message='No data to show'
) %}
{% call field() %}
{{ item.date | format_date_normal }}
{% endcall %}
<p class="table-show-more-link">
Only showing the last {{ notifications_by_type|length }} days
</p>
</div>
{% call field() %}
{{ item.emails|format_thousands }}
{% endcall %}
{% call field() %}
{{ item.sms|format_thousands }}
{% endcall %}
{% endcall %}
<p class="table-show-more-link">
Only showing the last {{ notifications_by_type|length }} days
</p>
</div>
<h2 class="govuk-heading-m">
@@ -84,7 +82,7 @@
) }}
</div>
</div>
<div class="table-wrapper">
<div class="table-overflow-x-auto">
<div class="dashboard-table">
{% call(item, row_number) list_table(
processing_time | reverse,
@@ -124,7 +122,7 @@
<span class="usa-sr-only">using Notify.</span>
</div>
</div>
<div class="table-wrapper">
<div class="table-overflow-x-auto">
<div class="dashboard-table">
{% call(item, row_number) list_table(
organizations_using_notify,

View File

@@ -16,7 +16,7 @@
</ol>
</nav>
<div class="grid-row margin-bottom-10">
<div class="tablet:grid-col-3 margin-top-4">
<div class="tablet:grid-col-2 margin-top-4">
<nav class="navigation">
<ul class="usa-sidenav">
@@ -41,7 +41,7 @@
</ul>
</nav>
</div>
<div class="grid-col-9 tablet:grid-col-9 padding-left-4 sub-content">
<div class="grid-col-10 tablet:grid-col-10 padding-left-4 sub-content">
{% block backLink %}{% endblock %}
<main id="main-content" role="main">
{% block content %}

View File

@@ -13,26 +13,26 @@
Email complaints
</h1>
<div class="table-overflow-x-auto">
{% call(item, row_number) list_table(
complaints,
caption="Complaints",
caption_visible=False,
empty_message='No complaints',
field_headings=['Notification Id', 'Service', 'Complaint type', 'Complaint Date'],
field_headings_visible=True
) %}
{% call(item, row_number) list_table(
complaints,
caption="Complaints",
caption_visible=False,
empty_message='No complaints',
field_headings=['Notification Id', 'Service', 'Complaint type', 'Complaint Date'],
field_headings_visible=True
) %}
{{ link_field(item.notification_id, url_for('main.view_notification', service_id=item.service_id, notification_id=item.notification_id)) }}
{{ link_field(item.notification_id, url_for('main.view_notification', service_id=item.service_id, notification_id=item.notification_id)) }}
{{ link_field(item.service_name, url_for('main.service_dashboard', service_id=item.service_id)) }}
{{ link_field(item.service_name, url_for('main.service_dashboard', service_id=item.service_id)) }}
{{ text_field(item.complaint_type) }}
{{ text_field(item.complaint_type) }}
{{ text_field(item.complaint_date|format_datetime_table if item.complaint_date else None) }}
{% endcall %}
{{ text_field(item.complaint_date|format_datetime_table if item.complaint_date else None) }}
{% endcall %}
</div>
{{ previous_next_navigation(prev_page, next_page) }}
{% endblock %}

View File

@@ -7,6 +7,7 @@
{% from "components/components/details/macro.njk" import usaDetails %}
{% macro services_table(services, caption) %}
<div class="table-overflow-x-auto">
{% call(item, row_number) mapping_table(
caption=caption,
caption_visible=False,
@@ -48,6 +49,7 @@
{% endfor %}
{% endcall %}
</div>
{% endmacro %}

View File

@@ -35,7 +35,7 @@ part.</p>
<h4>Calculation of message parts without special characters</h4>
<div class="bottom-gutter-3-2">
<div class="table-overflow-x-auto">
{% call mapping_table(
caption='Text message pricing',
field_headings=['Message length', 'Charge'],
@@ -86,7 +86,7 @@ recipients preferred language, but we are aware that, rarely, a phone carrier
to be calculated as detailed below.<p>
<h4>Calculation of message parts with special characters or non-romanized scripts</h4>
{% set accentedChars %}
<div class="bottom-gutter-3-2">
<div class="table-overflow-x-auto">
{% call mapping_table(
caption='Accented characters that affect text message charges',
field_headings=['Character', 'Description'],
@@ -151,7 +151,7 @@ to be calculated as detailed below.<p>
"html": accentedChars
}) }}
<div class="bottom-gutter-3-2">
<div class="table-overflow-x-auto">
{% call mapping_table(
caption='Pricing for text messages containing accented characters that affect the charges',
field_headings=['Message length', 'Charge'],

View File

@@ -16,7 +16,7 @@
<h1 class="font-body-lg">Settings</h1>
<div class="bottom-gutter-3-2 settings-table body-copy-table">
<div class="bottom-gutter-3-2 settings-table body-copy-table table-overflow-x-auto">
{% call mapping_table(
caption='General',

View File

@@ -20,7 +20,7 @@ Notify.gov
<div class="desktop:grid-col-7 tablet:grid-col-12">
<h1 class="font-serif-2xl usa-hero__heading">Reach people where they are with government-powered text messages</h1>
<p class="font-sans-lg">Notify.gov is a text message service that helps federal, state, local, tribal and territorial governments more effectively communicate with the people they serve.</p>
<div class="usa-button-group margin-bottom-5">
<div class="usa-button-group margin-bottom-5 flex-align-center">
<a class="usa-button usa-button login-button login-button--primary margin-right-2" href="{{ initial_signin_url }}">Sign in with <img src="{{ asset_url('images/logo-login.svg') }}" alt="Login.gov logo">
</a>
if you are an existing pilot partner

View File

@@ -70,8 +70,7 @@
</div> #}
{% if months %}
<div class="table-wrapper">
<div class="dashboard-table usage-table body-copy-table margin-top-4">
<div class="dashboard-table usage-table body-copy-table table-overflow-x-auto margin-top-4">
{% call(item, row_index) list_table(
months,
caption="Total spend",
@@ -122,7 +121,6 @@
{% endcall %}
</div>
</div>
{% endif %}
</div>

View File

@@ -30,7 +30,7 @@
{% block orgNavBreadcrumb %}{% include "/new/components/org_nav_breadcrumb.html" %}{% endblock %}
{% endif %}
<div class="grid-row margin-top-5">
<div class="tablet:grid-col-3">
<div class="tablet:grid-col-2">
{% block sideNavigation %}
{% if current_org.name %}
{% include "/new/components/org_nav.html" %}
@@ -44,7 +44,7 @@
#}
{% endblock %}
</div>
<div class="tablet:grid-col-9 tablet:padding-left-4">
<div class="tablet:grid-col-10 tablet:padding-left-4">
{% block beforeContent %}
{% block backLink %}{% endblock %}
{% endblock %}

View File

@@ -34,12 +34,6 @@ module "logo_upload_bucket" {
name = "${local.app_name}-logo-upload-bucket-${local.env}"
}
# ##########################################################################
# The following lines need to be commented out for the initial `terraform apply`
# It can be re-enabled after:
# 1) the api app has first been deployed
# 2) the admin app has first been deployed
###########################################################################
module "api_network_route" {
source = "../shared/container_networking"

View File

@@ -1,7 +1,6 @@
locals {
cf_org_name = "gsa-tts-benefits-studio"
cf_space_name = "notify-local-dev"
recursive_delete = true
key_name = "${var.username}-admin-dev-key"
}

View File

@@ -34,12 +34,6 @@ module "logo_upload_bucket" {
name = "${local.app_name}-logo-upload-bucket-${local.env}"
}
# ##########################################################################
# The following lines need to be commented out for the initial `terraform apply`
# It can be re-enabled after:
# 1) the api app has first been deployed
# 2) the admin app has first been deployed
###########################################################################
module "api_network_route" {
source = "../shared/container_networking"
@@ -50,22 +44,25 @@ module "api_network_route" {
}
# ##########################################################################
# The following lines need to be commented out for the initial `terraform apply`
# It can be re-enabled after:
# 1) the app has first been deployed
# 2) the route has been manually created by an OrgManager:
# This governs the name of our main website. Because domain names are unique,
# it only lives here in this one location in production. Resulting problem:
# it is hard to test. Create a temporary, similar code block (with a different
# subdomain) in Sandbox, test your changes there, and bring them here.
#
# Dependencies:
# 1) an app named notify-admin-production in Cloud.gov
# 2) this route, manually created by an OrgManager:
# `cf create-domain gsa-tts-benefits-studio beta.notify.gov`
# 3) the acme-challenge CNAME record must be created
# 3) the acme-challenge CNAME record
# https://cloud.gov/docs/services/external-domain-service/#how-to-create-an-instance-of-this-service
###########################################################################
module "domain" {
source = "github.com/18f/terraform-cloudgov//domain?ref=v0.7.1" # TODO: upgrade this
source = "github.com/GSA-TTS/terraform-cloudgov//domain?ref=v1.0.0"
cf_org_name = local.cf_org_name
cf_space_name = local.cf_space_name
app_name_or_id = "${local.app_name}-${local.env}"
name = "${local.app_name}-domain-${local.env}"
recursive_delete = false
cdn_plan_name = "domain"
domain_name = "beta.notify.gov"
}

View File

@@ -34,17 +34,11 @@ module "logo_upload_bucket" {
name = "${local.app_name}-logo-upload-bucket-${local.env}"
}
# ##########################################################################
# The following lines need to be commented out for the initial `terraform apply`
# It can be re-enabled after:
# 1) the api app has first been deployed
# 2) the admin app has first been deployed
###########################################################################
# module "api_network_route" {
# source = "../shared/container_networking"
module "api_network_route" { # API and Admin apps must both exist in Cloud
source = "../shared/container_networking"
# cf_org_name = local.cf_org_name
# cf_space_name = local.cf_space_name
# source_app_name = "${local.app_name}-${local.env}"
# destination_app_name = "notify-api-${local.env}"
# }
cf_org_name = local.cf_org_name
cf_space_name = local.cf_space_name
source_app_name = "${local.app_name}-${local.env}"
destination_app_name = "notify-api-${local.env}"
}

View File

@@ -34,12 +34,6 @@ module "logo_upload_bucket" {
name = "${local.app_name}-logo-upload-bucket-${local.env}"
}
# ##########################################################################
# The following lines need to be commented out for the initial `terraform apply`
# It can be re-enabled after:
# 1) the api app has first been deployed
# 2) the admin app has first been deployed
###########################################################################
module "api_network_route" {
source = "../shared/container_networking"