Merge pull request #1129 from GSA/1114-reviseexpand-on-recent-batch-table-on-the-dashboard-page

Revise/expand on "Recent Batch" table on the dashboard page.
This commit is contained in:
Carlo Costino
2024-01-26 15:03:08 -05:00
committed by GitHub
8 changed files with 232 additions and 238 deletions

View File

@@ -54,6 +54,7 @@ from app.formatters import (
format_datetime_normal,
format_datetime_relative,
format_datetime_short,
format_datetime_short_america,
format_day_of_week,
format_delta,
format_delta_days,
@@ -548,6 +549,7 @@ def add_template_filters(application):
format_datetime_24h,
format_datetime_normal,
format_datetime_short,
format_datetime_short_america,
valid_phone_number,
linkable_name,
format_date,

View File

@@ -377,6 +377,32 @@ td.table-empty-message {
}
}
.job-table {
.usa-table {
thead th.file-name {
width: 25%;
}
thead th.template {
width: 20%;
}
thead th.time-sent {
width: 30%;
}
thead th.sender {
width: 15%;
}
thead th.\#-of-recipients {
width: 5%;
}
thead th.report {
width: 5%;
}
th {
padding: 0.5rem 0.5rem;
}
}
}
#template-list {
max-height: 500px;
overflow-y: auto;

View File

@@ -98,6 +98,28 @@ def format_datetime_short(date):
)
def format_datetime_short_america(date):
return "{} at {}".format(format_date_numeric_america(date), format_time_12h(date))
def format_date_numeric_america(date):
date = parse_naive_dt(date)
preferred_tz = pytz.timezone(get_user_preferred_timezone())
return (
date.replace(tzinfo=timezone.utc).astimezone(preferred_tz).strftime("%m-%d-%Y")
)
def format_time_12h(date):
date = parse_naive_dt(date)
preferred_tz = pytz.timezone(get_user_preferred_timezone())
return (
date.replace(tzinfo=timezone.utc).astimezone(preferred_tz).strftime("%I:%M %p")
)
def format_datetime_relative(date):
return "{} at {} {}".format(
get_human_day(date), format_time_24h(date), get_user_preferred_timezone()

View File

@@ -47,54 +47,31 @@ def service_dashboard(service_id):
if not current_user.has_permissions("view_activity"):
return redirect(url_for("main.choose_template", service_id=service_id))
download_availability = []
notifications = notification_api_client.get_notifications_for_service(
service_id=service_id,
)["notifications"]
notificaton_job_ids = [
notification["job"]["id"]
for notification in notifications
if "job" in notification
]
jobs = []
for notificaton_job_id in notificaton_job_ids:
job_data = job_api_client.get_job(service_id, notificaton_job_id)["data"]
if job_data:
jobs.append(job_data)
job_response = job_api_client.get_jobs(service_id)
service_data_retention_days = 7
download_availability = []
for job in jobs:
message_type = job.get("template_type")
if message_type is not None:
service_data_retention_days = current_service.get_days_of_retention(
message_type
)
time_left = get_time_left(job["created_at"])
download_link = (
url_for(
".view_job_csv",
service_id=current_service.id,
job_id=job["id"],
jobs = [
{
"job_id": job["id"],
"time_left": get_time_left(job["created_at"]),
"download_link": url_for(
".view_job_csv", service_id=current_service.id, job_id=job["id"]
),
)
download_availability.append(
{
"job_id": job["id"],
"time_left": time_left,
"download_link": download_link,
}
)
"notification_count": job["notification_count"],
"created_by": job["created_by"],
}
for job in job_response["data"]
]
return render_template(
"views/dashboard/dashboard.html",
updates_url=url_for(".service_dashboard_updates", service_id=service_id),
partials=get_dashboard_partials(service_id),
notifications=notifications,
download_availability=download_availability,
jobs=jobs,
service_data_retention_days=service_data_retention_days,
)

View File

@@ -29,51 +29,69 @@
{{ ajax_block(partials, updates_url, 'template-statistics') }}
<h2 class="margin-top-4 margin-bottom-1">Batched Jobs</h2>
<h2 class="margin-top-4 margin-bottom-1">Recent Batches</h2>
<div class='job-table'>
{% call(item, row_number) list_table(
notifications,
caption="Batched Jobs",
caption_visible=False,
border_visible=True,
empty_message='No batched job messages found &thinsp;(messages are kept for {} days)'.format(service_data_retention_days)|safe,
field_headings=['Template Name','Date/Time', 'Download (CSV) Report'],
field_headings_visible=False
) %}
{% if item.job.original_file_name and item.job.id %}
{% call row_heading() %}
<a class="usa-link file-list-filename" href="/services/{{ item.service }}/jobs/{{ item.job.id }}">{{ item.job.original_file_name|replace('.csv', '') if item.job.id else '' }}</a>
{% endcall %}
{% call row_heading() %}
{{ item.status|format_notification_status_as_time(
item.created_at|format_datetime_short,
(item.updated_at or item.created_at)|format_datetime_short)
}}
{% endcall %}
{% call row_heading() %}
{% set availability = download_availability|selectattr('job_id', 'equalto', item.job.id)|first %}
{% if availability and availability.time_left != "Data no longer available" %}
<a class="usa-link file-list-filename" href="{{ availability.download_link[0] }}">{{ "Download" if item.job.original_file_name else '' }}</a>
<span>- {{ availability.time_left }}</span>
{% elif availability %}
<span>{{ availability.time_left }}</span>
{% endif %}
{% endcall %}
{% endif %}
{% endcall %}
<table class="usa-table usa-table--borderless width-full">
<thead class="table-field-headings">
<tr>
<th scope="col" class="table-field-heading-first file-name">
<span>File name</span>
</th>
<th scope="col" class="table-field-heading template">
<span>Template</span>
</th>
<th scope="col" class="table-field-heading time-sent">
<span>Time sent</span>
</th>
<th scope="col" class="table-field-heading sender">
<span>Sender</span>
</th>
<th scope="col" class="table-field-heading #-of-recipients">
<span># of Recipients</span>
</th>
<th scope="col" class="table-field-heading report">
<span>Report</span>
</th>
</tr>
</thead>
<tbody>
{% for notification in notifications[:5] %}
{% if notification %}
<tr class="table-row" id="{{ notification.job.id }}">
<th class="table-field">
{{ notification.job.original_file_name if notification.job.original_file_name else 'Manually entered number'}}
<br>
<a class="usa-link file-list-filename" href="/services/{{ notification.service }}/jobs/{{ notification.job.id }}">View Batch</a>
</th>
<th class="table-field">
{{ notification.template.name }}
</th>
<th class="table-field">
{{ (notification.updated_at or notification.created_at)| format_datetime_short_america }}
</th>
<th class="table-field">
{{ notification.created_by.name }}
</th>
{% set job_available = jobs|selectattr('job_id', 'equalto', notification.job.id)|first %}
<th class="table-field">
{{ job_available.notification_count if job_available else ''}}
</th>
<th class="table-field">
{% if job_available and job_available.time_left != "Data no longer available" %}
<a class="usa-link file-list-filename" href="{{ job_available.download_link }}">
{{ "Download" if job_available.job_id else '' }}</a>
<span class="usa-hint">{{ job_available.time_left }}</span>
{% elif job_available %}
<span>{{ job_available.time_left }}</span>
{% endif %}
</th>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
{% if show_pagination %}
{{ previous_next_navigation(prev_page, next_page) }}
{% elif next_page %}
<p class="table-show-more-link">
Only showing the first 50 messages
</p>
{% endif %}
<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>