diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a87db3fcd..7ffbbc290 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -20,3 +20,8 @@ Please enter a detailed description here. * Consideration 1 * Consideration 2 * Consideration ... + +## A11y Checks (if applicable) + +* Conduct automated tests through [AxeDevTools](https://www.deque.com/axe/devtools/) and [WAVE](https://wave.webaim.org/) +* Review the [Manual Checklist](https://docs.google.com/document/d/192bBXStebdXWtYhZQ73qaWMJhGcuSB1W6c9YBXhWZvc/edit?usp=sharing) diff --git a/app/assets/javascripts/activityChart.js b/app/assets/javascripts/activityChart.js index 6dfc73fbb..f12774c68 100644 --- a/app/assets/javascripts/activityChart.js +++ b/app/assets/javascripts/activityChart.js @@ -2,6 +2,8 @@ if (document.getElementById('activityChartContainer')) { let currentType = 'service'; + const tableContainer = document.getElementById('activityContainer'); + const currentUserName = tableContainer.getAttribute('data-currentUserName'); const COLORS = { delivered: '#0076d6', failed: '#fa9441', @@ -282,27 +284,58 @@ subTitle.textContent = `${selectedText} - last 7 days`; fetchData(selectedValue); - // Update ARIA live region const liveRegion = document.getElementById('aria-live-account'); liveRegion.textContent = `Data updated for ${selectedText} - last 7 days`; - // Switch tables based on dropdown selection - const selectedTable = selectedValue === "individual" ? "table1" : "table2"; - const tables = document.querySelectorAll('.table-overflow-x-auto'); - tables.forEach(function(table) { - table.classList.add('hidden'); // Hide all tables by adding the hidden class - table.classList.remove('visible'); // Ensure they are not visible - }); - const tableToShow = document.getElementById(selectedTable); - tableToShow.classList.remove('hidden'); // Remove hidden class - tableToShow.classList.add('visible'); // Add visible class + const tableHeading = document.querySelector('#tableActivity h2'); + const senderColumns = document.querySelectorAll('.sender-column'); + const allRows = document.querySelectorAll('#activity-table tbody tr'); + const caption = document.querySelector('#activity-table caption'); + + if (selectedValue === 'individual') { + + tableHeading.textContent = 'My activity'; + caption.textContent = `Table showing the sent jobs for ${currentUserName}`; + + senderColumns.forEach(col => { + col.style.display = 'none'; + }); + + allRows.forEach(row => row.style.display = 'none'); + + const userRows = Array.from(allRows).filter(row => { + const senderCell = row.querySelector('.sender-column'); + const rowSender = senderCell ? senderCell.textContent.trim() : ''; + return rowSender === currentUserName; + }); + + userRows.slice(0, 5).forEach(row => { + row.style.display = ''; + }); + } else { + + tableHeading.textContent = 'Service activity'; + caption.textContent = `Table showing the sent jobs for service`; + + senderColumns.forEach(col => { + col.style.display = ''; + }); + + allRows.forEach((row, index) => { + row.style.display = (index < 5) ? '' : 'none'; + }); + } }; document.addEventListener('DOMContentLoaded', function() { // Initialize activityChart chart and table with service data by default fetchData(currentType); - // Add event listener to the dropdown + const allRows = Array.from(document.querySelectorAll('#activity-table tbody tr')); + allRows.forEach((row, index) => { + row.style.display = (index < 5) ? '' : 'none'; + }); + const dropdown = document.getElementById('options'); dropdown.addEventListener('change', handleDropdownChange); }); diff --git a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss index 7fafb8276..0bb1aab7e 100644 --- a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss +++ b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss @@ -1024,7 +1024,3 @@ nav.nav { font-size: units(3); font-weight: bold; } - -.form-control-error { - border: 4px solid #b10e1e -} diff --git a/app/content/get-started.md b/app/content/get-started.md index 7d18aacbd..c97b9efc6 100644 --- a/app/content/get-started.md +++ b/app/content/get-started.md @@ -5,7 +5,7 @@ Explore Notify, add team members, and practice [sending messages to teammates](/using-notify/trial-mode). 2. ## Personalize content -Learn how to [personalize messages](/using-notify/guidance) to increase response. +Learn how to [personalize messages](/using-notify/how-to) to increase response. 3. ## Check delivery status [Analyze the delivery](/using-notify/delivery-status) of your messages and download reports diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py index 8013acb9d..1f8cac573 100644 --- a/app/main/views/dashboard.py +++ b/app/main/views/dashboard.py @@ -14,7 +14,7 @@ from app import ( service_api_client, template_statistics_client, ) -from app.formatters import format_date_numeric, format_datetime_numeric, get_time_left +from app.formatters import format_date_numeric, format_datetime_numeric from app.main import main from app.main.views.user_profile import set_timezone from app.statistics_utils import get_formatted_percentage @@ -62,32 +62,14 @@ def service_dashboard(service_id): job_response = job_api_client.get_jobs(service_id)["data"] service_data_retention_days = 7 - 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"] - ), - "view_job_link": url_for( - ".view_job", service_id=current_service.id, job_id=job["id"] - ), - "created_at": job["created_at"], - "processing_finished": job.get("processing_finished"), - "processing_started": job.get("processing_started"), - "notification_count": job["notification_count"], - "created_by": job["created_by"], - "template_name": job["template_name"], - "original_file_name": job["original_file_name"], - } - for job in job_response - if job["job_status"] != "cancelled" - ] + filtered_jobs = [job for job in job_response if job["job_status"] != "cancelled"] + sorted_jobs = sorted(filtered_jobs, key=lambda job: job["created_at"], reverse=True) + return render_template( "views/dashboard/dashboard.html", updates_url=url_for(".service_dashboard_updates", service_id=service_id), partials=get_dashboard_partials(service_id), - jobs=jobs, + jobs=sorted_jobs, service_data_retention_days=service_data_retention_days, sms_sent=sms_sent, sms_allowance_remaining=sms_allowance_remaining, diff --git a/app/main/views/index.py b/app/main/views/index.py index 8b63d2bd8..5c0312afc 100644 --- a/app/main/views/index.py +++ b/app/main/views/index.py @@ -217,11 +217,11 @@ def benchmark_performance(): ) -@main.route("/using-notify/guidance") +@main.route("/using-notify/how-to") @user_is_logged_in -def guidance_index(): +def how_to(): return render_template( - "views/guidance/index.html", + "views/how-to/index.html", navigation_links=using_notify_nav(), ) @@ -266,29 +266,29 @@ def join_notify(): ) -@main.route("/using-notify/guidance/create-and-send-messages") +@main.route("/using-notify/how-to/create-and-send-messages") @user_is_logged_in def create_and_send_messages(): return render_template( - "views/guidance/create-and-send-messages.html", + "views/how-to/create-and-send-messages.html", navigation_links=using_notify_nav(), ) -@main.route("/using-notify/guidance/edit-and-format-messages") +@main.route("/using-notify/how-to/edit-and-format-messages") @user_is_logged_in def edit_and_format_messages(): return render_template( - "views/guidance/edit-and-format-messages.html", + "views/how-to/edit-and-format-messages.html", navigation_links=using_notify_nav(), ) -@main.route("/using-notify/guidance/send-files-by-email") +@main.route("/using-notify/how-to/send-files-by-email") @user_is_logged_in def send_files_by_email(): return render_template( - "views/guidance/send-files-by-email.html", + "views/how-to/send-files-by-email.html", navigation_links=using_notify_nav(), ) diff --git a/app/main/views/sub_navigation_dictionaries.py b/app/main/views/sub_navigation_dictionaries.py index 3b2cf84c1..db086e511 100644 --- a/app/main/views/sub_navigation_dictionaries.py +++ b/app/main/views/sub_navigation_dictionaries.py @@ -2,7 +2,7 @@ def using_notify_nav(): nav_items = [ {"name": "Get started", "link": "main.get_started"}, { - "name": "Best Practices", + "name": "Best practices", "link": "main.best_practices", "sub_navigation_items": [ { @@ -33,8 +33,8 @@ def using_notify_nav(): }, {"name": "Trial mode", "link": "main.trial_mode_new"}, {"name": "Tracking usage", "link": "main.pricing"}, - {"name": "Delivery Status", "link": "main.message_status"}, - {"name": "Guidance", "link": "main.guidance_index"}, + {"name": "Delivery status", "link": "main.message_status"}, + {"name": "How to", "link": "main.how_to"}, ] return nav_items diff --git a/app/main/views/templates.py b/app/main/views/templates.py index 3a7315db7..5c59e1e7c 100644 --- a/app/main/views/templates.py +++ b/app/main/views/templates.py @@ -645,7 +645,6 @@ def edit_service_template(service_id, template_id): return render_template( "views/edit-{}-template.html".format(template["template_type"]), form=form, - errors=form.errors if form.errors else None, template=template, heading_action="Edit", ) diff --git a/app/navigation.py b/app/navigation.py index 424d03ae3..f20df4e5f 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -54,7 +54,7 @@ class HeaderNavigation(Navigation): "pricing", "trial_mode_new", "message_status", - "guidance_index", + "how_to", }, "accounts-or-dashboard": { "conversation", diff --git a/app/templates/components/components/input/template.njk b/app/templates/components/components/input/template.njk index 9e2cff08c..7f5634651 100644 --- a/app/templates/components/components/input/template.njk +++ b/app/templates/components/components/input/template.njk @@ -42,7 +42,5 @@ {%- if describedBy %} aria-describedby="{{ describedBy }}"{% endif %} {%- if params.autocomplete %} autocomplete="{{ params.autocomplete}}"{% endif %} {%- if params.pattern %} pattern="{{ params.pattern }}"{% endif %} - {%- for attribute, value in params.attributes %} {{ attribute }}="{{ value }}"{% endfor -%} - {%- if params.required %} required{% endif %} -/> + {%- for attribute, value in params.attributes %} {{ attribute }}="{{ value }}"{% endfor -%}> diff --git a/app/templates/components/form.html b/app/templates/components/form.html index 5875a19a9..17cabc7f0 100644 --- a/app/templates/components/form.html +++ b/app/templates/components/form.html @@ -19,6 +19,7 @@ data-{{ key }}="{{ val }}" {% endif %} {% endfor %} + novalidate > {{ caller() }} diff --git a/app/templates/components/textbox.html b/app/templates/components/textbox.html index e8b6f813d..3e479cbce 100644 --- a/app/templates/components/textbox.html +++ b/app/templates/components/textbox.html @@ -13,13 +13,22 @@ safe_error_message=False, rows=8, extra_form_group_classes='', - placeholder='', - required=None + placeholder='' ) %}
+ {% if not safe_error_message %}{{ field.errors[0] }}{% else %}{{ field.errors[0]|safe }}{% endif %} +
+| Job ID# | +Template | +Job status | +Sender + | +# of Recipients | +
|---|---|---|---|---|
| + + {{ job.id[:8] if job.id else 'Manually entered number' }} + + | +{{ job.template_name }} | ++ {% if job.scheduled_for and not job.processing_finished %} + Scheduled for {{ job.scheduled_for|format_datetime_table }} + {% elif job.processing_finished and not job.statistics|selectattr('status', 'equalto', 'sending')|list %} + Sent on {{ job.processing_finished|format_datetime_table }} + {% elif job.processing_started %} + Sending since {{ job.processing_started|format_datetime_table }} + {% else %} + Pending since {{ job.created_at|format_datetime_table }} + {% endif %} + | +{{ job.created_by.name }} | +{{ job.notification_count }} | +
| Job ID# | -Template | -Job status | -Sender | -# of Recipients | -
|---|---|---|---|---|
| - - {{ job.job_id[:8] if job.job_id else 'Manually entered number' }} - - | -{{ job.template_name }} | -Sent on - {{ (job.processing_finished if job.processing_finished else job.processing_started - if job.processing_started else job.created_at)|format_datetime_table }} - | -{{ job.created_by.name }} | -{{ job.notification_count }} | -
Notify makes it easy to send personalized messages from a single template.
-See how to personalize your content.
+See how to personalize your content.
To send a batch of messages at once, upload a list of contact details to Notify. You can also schedule the date and time you want them to be sent.
diff --git a/app/templates/views/guides/benchmark-performance.html b/app/templates/views/guides/benchmark-performance.html index bd2662fbe..c302fc5b8 100644 --- a/app/templates/views/guides/benchmark-performance.html +++ b/app/templates/views/guides/benchmark-performance.html @@ -8,7 +8,7 @@ {% endblock %} {% block content_column_content %} -{{ breadcrumbs.breadcrumb(page_title, "Best Practices", "main.best_practices") }} +{{ breadcrumbs.breadcrumb(page_title, "Best practices", "main.best_practices") }}For texting the public
Effectively reaching your audience and supporting your program’s goals starts with strategically planning out what
text messages can help you achieve and how to approach a thoughtful rollout.
diff --git a/app/templates/views/guides/clear-goals.html b/app/templates/views/guides/clear-goals.html
index d1054e3a9..a6e3a742b 100644
--- a/app/templates/views/guides/clear-goals.html
+++ b/app/templates/views/guides/clear-goals.html
@@ -8,7 +8,7 @@
{% endblock %}
{% block content_column_content %}
-{{ breadcrumbs.breadcrumb(page_title, "Best Practices", "main.best_practices") }}
+{{ breadcrumbs.breadcrumb(page_title, "Best practices", "main.best_practices") }}
Notify allows you to easily create templates for messages for your recipients. You can customize messages to encourage
your recipient to manage their benefits and increase follow-through.{{page_title}}
diff --git a/app/templates/views/guides/establish-trust.html b/app/templates/views/guides/establish-trust.html
index 0ab95c73a..026e9da81 100644
--- a/app/templates/views/guides/establish-trust.html
+++ b/app/templates/views/guides/establish-trust.html
@@ -10,7 +10,7 @@
{% endblock %}
{% block content_column_content %}
-{{ breadcrumbs.breadcrumb(page_title, "Best Practices", "main.best_practices") }}
+{{ breadcrumbs.breadcrumb(page_title, "Best practices", "main.best_practices") }}
{{page_title}}
diff --git a/app/templates/views/guides/multiple-languages.html b/app/templates/views/guides/multiple-languages.html
index f295df308..b8bb7883c 100644
--- a/app/templates/views/guides/multiple-languages.html
+++ b/app/templates/views/guides/multiple-languages.html
@@ -8,7 +8,7 @@
{% endblock %}
{% block content_column_content %}
-{{ breadcrumbs.breadcrumb(page_title, "Best Practices", "main.best_practices") }}
+{{ breadcrumbs.breadcrumb(page_title, "Best practices", "main.best_practices") }}
{{page_title}}
diff --git a/app/templates/views/guides/rules-and-regulations.html b/app/templates/views/guides/rules-and-regulations.html
index 5943e462d..8ad6d000b 100644
--- a/app/templates/views/guides/rules-and-regulations.html
+++ b/app/templates/views/guides/rules-and-regulations.html
@@ -8,7 +8,7 @@
{% endblock %}
{% block content_column_content %}
-{{ breadcrumbs.breadcrumb(page_title, "Best Practices", "main.best_practices") }}
+{{ breadcrumbs.breadcrumb(page_title, "Best practices", "main.best_practices") }}
{{page_title}}
diff --git a/app/templates/views/guides/write-for-action.html b/app/templates/views/guides/write-for-action.html
index ff382864a..31ac2aa84 100644
--- a/app/templates/views/guides/write-for-action.html
+++ b/app/templates/views/guides/write-for-action.html
@@ -9,7 +9,7 @@
{% endblock %}
{% block content_column_content %}
-{{ breadcrumbs.breadcrumb(page_title, "Best Practices", "main.best_practices") }}
+{{ breadcrumbs.breadcrumb(page_title, "Best practices", "main.best_practices") }}
{{page_title}}
diff --git a/app/templates/views/guidance/create-and-send-messages.html b/app/templates/views/how-to/create-and-send-messages.html
similarity index 100%
rename from app/templates/views/guidance/create-and-send-messages.html
rename to app/templates/views/how-to/create-and-send-messages.html
diff --git a/app/templates/views/guidance/edit-and-format-messages.html b/app/templates/views/how-to/edit-and-format-messages.html
similarity index 100%
rename from app/templates/views/guidance/edit-and-format-messages.html
rename to app/templates/views/how-to/edit-and-format-messages.html
diff --git a/app/templates/views/guidance/index.html b/app/templates/views/how-to/index.html
similarity index 95%
rename from app/templates/views/guidance/index.html
rename to app/templates/views/how-to/index.html
index 062bae555..aa2361cb6 100644
--- a/app/templates/views/guidance/index.html
+++ b/app/templates/views/how-to/index.html
@@ -4,11 +4,11 @@
{% from "components/service-link.html" import service_link %}
{% block per_page_title %}
- Guidance
+ How to
{% endblock %}
{% block content_column_content %}
-Guidance
+How to
Notify is designed to be easy to use.
| Test User |
| Other User |
| Test User |
| Test User |
| Other User |
| Test User |
| Test User |