mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-19 05:59:44 -04:00
Merge pull request #2712 from GSA/2709-bug-sorting-error-on-activity-page
Improved job/activity list ordering and display
This commit is contained in:
@@ -34,6 +34,7 @@ from app.config import configs
|
|||||||
from app.extensions import redis_client
|
from app.extensions import redis_client
|
||||||
from app.formatters import (
|
from app.formatters import (
|
||||||
convert_markdown_template,
|
convert_markdown_template,
|
||||||
|
convert_time_unixtimestamp,
|
||||||
convert_to_boolean,
|
convert_to_boolean,
|
||||||
format_auth_type,
|
format_auth_type,
|
||||||
format_billions,
|
format_billions,
|
||||||
@@ -672,6 +673,7 @@ def add_template_filters(application):
|
|||||||
format_thousands,
|
format_thousands,
|
||||||
id_safe,
|
id_safe,
|
||||||
convert_to_boolean,
|
convert_to_boolean,
|
||||||
|
convert_time_unixtimestamp,
|
||||||
format_list_items,
|
format_list_items,
|
||||||
iteration_count,
|
iteration_count,
|
||||||
recipient_count,
|
recipient_count,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from flask import abort, render_template, request, url_for
|
from flask import abort, render_template, request, url_for
|
||||||
|
|
||||||
from app import current_service, job_api_client
|
from app import current_service, job_api_client
|
||||||
from app.formatters import convert_time_unixtimestamp, get_time_left
|
from app.formatters import get_time_left
|
||||||
from app.main import main
|
from app.main import main
|
||||||
from app.utils.pagination import (
|
from app.utils.pagination import (
|
||||||
generate_next_dict,
|
generate_next_dict,
|
||||||
@@ -78,47 +78,43 @@ def handle_pagination(jobs, service_id, page):
|
|||||||
return prev_page, next_page, pagination
|
return prev_page, next_page, pagination
|
||||||
|
|
||||||
|
|
||||||
|
JOB_STATUS_DELIVERED = "delivered"
|
||||||
|
JOB_STATUS_FAILED = "failed"
|
||||||
|
|
||||||
|
|
||||||
|
def get_job_statistics(job, status):
|
||||||
|
statistics = job.get("statistics", [])
|
||||||
|
for stat in statistics:
|
||||||
|
if stat.get("status") == status:
|
||||||
|
return stat.get("count")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def create_job_dict_entry(job):
|
||||||
|
job_id = job.get("id")
|
||||||
|
can_download = get_time_left(job.get("created_at")) != "Data no longer available"
|
||||||
|
activity_time = job.get("processing_started") or job.get("created_at")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"job_id": job_id,
|
||||||
|
"can_download": can_download,
|
||||||
|
"download_link": (
|
||||||
|
url_for(".view_job_csv", service_id=current_service.id, job_id=job_id)
|
||||||
|
if can_download
|
||||||
|
else None
|
||||||
|
),
|
||||||
|
"view_job_link": url_for(
|
||||||
|
".view_job", service_id=current_service.id, job_id=job_id
|
||||||
|
),
|
||||||
|
"activity_time": activity_time,
|
||||||
|
"created_by": job.get("created_by"),
|
||||||
|
"template_name": job.get("template_name"),
|
||||||
|
"delivered_count": get_job_statistics(job, JOB_STATUS_DELIVERED),
|
||||||
|
"failed_count": get_job_statistics(job, JOB_STATUS_FAILED),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def generate_job_dict(jobs):
|
def generate_job_dict(jobs):
|
||||||
return [
|
if not jobs or not jobs.get("data"):
|
||||||
{
|
return []
|
||||||
"job_id": job["id"],
|
return [create_job_dict_entry(job) for job in jobs["data"]]
|
||||||
"time_left": get_time_left(job["created_at"]),
|
|
||||||
"download_link": url_for(
|
|
||||||
".view_job_csv", service_id=current_service.id, job_id=job["id"]
|
|
||||||
),
|
|
||||||
"view_job_link": url_for(
|
|
||||||
".view_job", service_id=current_service.id, job_id=job["id"]
|
|
||||||
),
|
|
||||||
"created_at": job["created_at"],
|
|
||||||
"time_sent_data_value": convert_time_unixtimestamp(
|
|
||||||
job["processing_finished"]
|
|
||||||
if job["processing_finished"]
|
|
||||||
else (
|
|
||||||
job["processing_started"]
|
|
||||||
if job["processing_started"]
|
|
||||||
else job["created_at"]
|
|
||||||
)
|
|
||||||
),
|
|
||||||
"processing_finished": job["processing_finished"],
|
|
||||||
"processing_started": job["processing_started"],
|
|
||||||
"created_by": job["created_by"],
|
|
||||||
"template_name": job["template_name"],
|
|
||||||
"delivered_count": next(
|
|
||||||
(
|
|
||||||
stat["count"]
|
|
||||||
for stat in job.get("statistics", [])
|
|
||||||
if stat["status"] == "delivered"
|
|
||||||
),
|
|
||||||
None,
|
|
||||||
),
|
|
||||||
"failed_count": next(
|
|
||||||
(
|
|
||||||
stat["count"]
|
|
||||||
for stat in job.get("statistics", [])
|
|
||||||
if stat["status"] == "failed"
|
|
||||||
),
|
|
||||||
None,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
for job in jobs["data"]
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -43,10 +43,9 @@ def service_dashboard(service_id):
|
|||||||
service_data_retention_days = 7
|
service_data_retention_days = 7
|
||||||
|
|
||||||
active_jobs = [job for job in job_response if job["job_status"] != "cancelled"]
|
active_jobs = [job for job in job_response if job["job_status"] != "cancelled"]
|
||||||
sorted_jobs = sorted(active_jobs, key=lambda job: job["created_at"], reverse=True)
|
|
||||||
job_lists = [
|
job_lists = [
|
||||||
{**job_dict, "finished_processing": job_is_finished(job_dict)}
|
{**job_dict, "finished_processing": job_is_finished(job_dict)}
|
||||||
for job_dict in sorted_jobs
|
for job_dict in active_jobs
|
||||||
]
|
]
|
||||||
|
|
||||||
total_messages = service_api_client.get_service_message_ratio(service_id)
|
total_messages = service_api_client.get_service_message_ratio(service_id)
|
||||||
|
|||||||
@@ -70,7 +70,7 @@
|
|||||||
<span>Template</span>
|
<span>Template</span>
|
||||||
</th>
|
</th>
|
||||||
<th data-sortable scope="col" role="columnheader" class="table-field-heading">
|
<th data-sortable scope="col" role="columnheader" class="table-field-heading">
|
||||||
<span>Time sent</span>
|
<span>Started</span>
|
||||||
</th>
|
</th>
|
||||||
<th data-sortable scope="col" role="columnheader" class="table-field-heading">
|
<th data-sortable scope="col" role="columnheader" class="table-field-heading">
|
||||||
<span>Sender</span>
|
<span>Sender</span>
|
||||||
@@ -96,13 +96,12 @@
|
|||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="table-field template">{{ job.template_name }}</td>
|
<td class="table-field template">{{ job.template_name }}</td>
|
||||||
<td data-sort-value="{{job.time_sent_data_value}}" class="table-field time-sent">
|
<td data-sort-value="{{ job.activity_time | convert_time_unixtimestamp }}" class="table-field time-sent">
|
||||||
{{ (job.processing_finished if job.processing_finished else job.processing_started
|
{{ job.activity_time|format_datetime_table }}
|
||||||
if job.processing_started else job.created_at)|format_datetime_table }}
|
|
||||||
</td>
|
</td>
|
||||||
<td class="table-field sender">{{ job.created_by.name }}</td>
|
<td class="table-field sender">{{ job.created_by.name }}</td>
|
||||||
<td class="table-field report">
|
<td class="table-field report">
|
||||||
{% if job.time_left != "Data no longer available" %}
|
{% if job.can_download %}
|
||||||
<a href="{{ job.download_link }}">
|
<a href="{{ job.download_link }}">
|
||||||
<img src="{{ url_for('static', filename='img/material-icons/file_download.svg') }}" alt="">
|
<img src="{{ url_for('static', filename='img/material-icons/file_download.svg') }}" alt="">
|
||||||
<span class="usa-sr-only">Download report link</span>
|
<span class="usa-sr-only">Download report link</span>
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ def test_all_activity(
|
|||||||
expected_headers = [
|
expected_headers = [
|
||||||
"Job ID#",
|
"Job ID#",
|
||||||
"Template",
|
"Template",
|
||||||
"Time sent",
|
"Started",
|
||||||
"Sender",
|
"Sender",
|
||||||
"Report",
|
"Report",
|
||||||
"Delivered",
|
"Delivered",
|
||||||
|
|||||||
Reference in New Issue
Block a user