diff --git a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss index c6b65d4e6..addf9cc7a 100644 --- a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss +++ b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss @@ -381,28 +381,29 @@ 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; - } + width: 100%; + border-collapse: collapse; + td.file-name { + width: 25%; + overflow-wrap: anywhere; + } + td.template { + width: 20%; + } + td.time-sent { + width: 20%; + } + td.sender { + width: 15%; + } + td.count-of-recipients { + width: 5%; + } + td.report { + width: 5%; + } + th { + padding: 0.5rem 0.5rem; } } diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py index a88203ae7..c2a11eccf 100644 --- a/app/main/views/dashboard.py +++ b/app/main/views/dashboard.py @@ -1,4 +1,5 @@ import calendar +from collections import defaultdict from datetime import datetime from functools import partial from itertools import groupby @@ -47,31 +48,38 @@ def service_dashboard(service_id): if not current_user.has_permissions("view_activity"): return redirect(url_for("main.choose_template", service_id=service_id)) - notifications = notification_api_client.get_notifications_for_service( - service_id=service_id, - )["notifications"] - - job_response = job_api_client.get_jobs(service_id) - + job_response = job_api_client.get_jobs(service_id)["data"] + notifications_response = notification_api_client.get_notifications_for_service(service_id)["notifications"] service_data_retention_days = 7 - jobs = [ + + aggregate_notifications_by_job = defaultdict(list) + for notification in notifications_response: + job_id = notification.get("job", {}).get("id", None) + if job_id: + aggregate_notifications_by_job[job_id].append(notification) + + job_and_notifications = [ { "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"] ), + "view_job_link": url_for( + ".view_job", service_id=current_service.id, job_id=job["id"] + ), + "created_at": job["created_at"], "notification_count": job["notification_count"], "created_by": job["created_by"], + "notifications": aggregate_notifications_by_job.get(job["id"], []), } - for job in job_response["data"] + for job in job_response ] 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, - jobs=jobs, + job_and_notifications=job_and_notifications, service_data_retention_days=service_data_retention_days, ) diff --git a/app/templates/views/dashboard/dashboard.html b/app/templates/views/dashboard/dashboard.html index 9c51ea47c..3ea62a273 100644 --- a/app/templates/views/dashboard/dashboard.html +++ b/app/templates/views/dashboard/dashboard.html @@ -28,66 +28,70 @@ {{ ajax_block(partials, updates_url, 'totals') }} {{ ajax_block(partials, updates_url, 'template-statistics') }} -

Recent Batches

-
- +
+
- - - - - - - {% for notification in notifications[:5] %} - {% if notification %} - - - - - - {% set job_available = jobs|selectattr('job_id', 'equalto', notification.job.id)|first %} - - - - {% endif %} - {% endfor %} + {% if job_and_notifications %} + {% for job in job_and_notifications[:5] %} + {% if job.job_id and job.notifications %} + {% set notification = job.notifications[0] %} + + + + + + + + + {% endif %} + {% endfor %} + {% else %} + + + + {% endif %}
+ File name + Template + Time sent + Sender + # of Recipients + Report
- {{ notification.job.original_file_name if notification.job.original_file_name else 'Manually entered number'}} -
- View Batch -
- {{ notification.template.name }} - - {{ notification.created_at | format_datetime_short_america }} - - {{ notification.created_by.name }} - - {{ job_available.notification_count if job_available else ''}} - - {% if job_available and job_available.time_left != "Data no longer available" %} - - {{ "Download" if job_available.job_id else '' }} - {{ job_available.time_left }} - {% elif job_available %} - {{ job_available.time_left }} - {% endif %} -
+ {{ notification.job.original_file_name if notification.job.original_file_name else 'Manually entered number'}} +
+ View Batch +
+ {{ notification.template.name }} + + {{ job.created_at | format_datetime_short_america }} + + {{ notification.created_by.name }} + + {{ job.notification_count}} + + {% if notification and job.time_left != "Data no longer available" %} + Download + {{ job.time_left }} + {% elif job %} + {{ job.time_left }} + {% endif %} +
No batched job messages found  (messages are kept for {{ service_data_retention_days }} days).
diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index 8e9ecb531..53a8a7feb 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -40,7 +40,7 @@ FAKE_ONE_OFF_NOTIFICATION = { "created_by": { "email_address": "grsrbsrgsrf@fake.gov", "id": "de059e0a-42e5-48bb-939e-4f76804ab739", - "name": "grsrbsrgsrf", + "name": "mocked_user", }, "document_download_count": None, "id": "a3442b43-0ba1-4854-9e0a-d2fba1cc9b81", @@ -71,7 +71,7 @@ FAKE_ONE_OFF_NOTIFICATION = { "template": { "content": "((day of week)) and ((fave color))", "id": "bd9caa7e-00ee-4c5a-839e-10ae1a7e6f73", - "name": "personalized", + "name": "Template Testing", "redact_personalisation": False, "subject": None, "template_type": "sms", @@ -94,7 +94,7 @@ MOCK_JOBS = { "id": "mocked_user_id", "name": "mocked_user", }, - "id": "mocked_notification_id", + "id": "55b242b5-9f62-4271-aff7-039e9c320578", "job_status": "finished", "notification_count": 1, "original_file_name": "mocked_file.csv", @@ -113,6 +113,19 @@ MOCK_JOBS = { ] } +MOCK_JOBS_AND_NOTIFICATIONS = [ + { + "created_at": MOCK_JOBS["data"][0]["created_at"], + "created_by": MOCK_JOBS["data"][0]["created_by"], + "download_link": "/services/21b3ee3d-1cb0-4666-bfa0-9c5ac26d3fe3/jobs/463b5ecb-4e32-43e5-aa90-0234d19fceaa.csv", + "job_id": "55b242b5-9f62-4271-aff7-039e9c320578", + "notification_count": MOCK_JOBS["data"][0]["notification_count"], + "notifications": FAKE_ONE_OFF_NOTIFICATION["notifications"], + "time_left": "Data available for 7 days", + "view_job_link": "/services/21b3ee3d-1cb0-4666-bfa0-9c5ac26d3fe3/jobs/463b5ecb-4e32-43e5-aa90-0234d19fceaa" + }, +] + stub_template_stats = [ { "template_type": "sms", @@ -1855,11 +1868,11 @@ def test_service_dashboard_shows_batched_jobs( page = client_request.get("main.service_dashboard", service_id=SERVICE_ONE_ID) - job_table = page.find("div", class_="job-table") + job_table_body = page.find("table", class_="job-table") - # Check if the "Job" table exists - assert job_table is not None + rows = job_table_body.find_all("tbody")[0].find_all("tr") - table_rows = job_table.find_all("tbody")[0].find_all("tr") + # # Check if the "Job" table exists + assert job_table_body is not None - assert len(table_rows) == 1 + assert len(rows) == 1