code review feedback

This commit is contained in:
Kenneth Kehl
2025-01-29 13:22:22 -08:00
44 changed files with 981 additions and 2081 deletions

View File

@@ -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 -%}>
</div>

View File

@@ -19,6 +19,7 @@
data-{{ key }}="{{ val }}"
{% endif %}
{% endfor %}
novalidate
>
{{ caller() }}
</form>

View File

@@ -13,13 +13,22 @@
safe_error_message=False,
rows=8,
extra_form_group_classes='',
placeholder='',
required=None
placeholder=''
) %}
<div
class="usa-form-group{% if field.errors %} usa-form-group--error{% endif %} {{ extra_form_group_classes }}"
class="form-group{% if field.errors %} form-group-error{% endif %} {{ extra_form_group_classes }}"
data-module="{% if autofocus %}autofocus{% elif colour_preview %}colour-preview{% endif %}"
>
{% if field.errors %}
<div class="usa-alert usa-alert--error edit-textbox-error-mt" role="alert">
<div class="usa-alert__body">
<h4 class="usa-alert__heading">Error message</h4>
<p class="usa-alert__text" data-module="track-error" data-error-type="{{ field.errors[0] }}" data-error-label="{{ field.name }}">
{% if not safe_error_message %}{{ field.errors[0] }}{% else %}{{ field.errors[0]|safe }}{% endif %}
</p>
</div>
</div>
{% endif %}
<label class="usa-label" for="{{ field.name }}">
{% if label %}
{{ label }}
@@ -32,12 +41,6 @@
{{ hint }}
</div>
{% endif %}
{% if field.errors %}
<span id="{{ field.name}}-error" class="usa-error-message" data-module="track-error" data-error-type="{{ field.errors[0] }}" data-error-label="{{ field.name }}">
<span class="usa-sr-only">Error:</span>
{% if not safe_error_message %}{{ field.errors[0] }}{% else %}{{ field.errors[0]|safe }}{% endif %}
</span>
{% endif %}
{%
if highlight_placeholders or autosize
%}
@@ -56,8 +59,6 @@
data_highlight_placeholders='true' if highlight_placeholders else 'false',
rows=rows|string,
placeholder=placeholder,
aria_describedby=field.name+"-error",
required='required' if required else None,
**kwargs
) }}
{% if suffix %}

View File

@@ -21,11 +21,11 @@
<div class="ajax-block-container">
<p class='bottom-gutter'>
{% if job.still_processing or arrived_from_preview_page_url %}
{% if not job.finished_processing %}
{% if job.scheduled_for %}
<div class="usa-alert usa-alert--info">
<div class="usa-alert__body">
<h2 class="usa-alert__heading">Your text has been scheduled</h2>
<h2 class="usa-alert__heading">Your message has been scheduled</h2>
<p class="usa-alert__text">
{{ job.template_name }} - {{ current_service.name }} was scheduled on {{ job.scheduled_for|format_datetime_normal }} by {{ job.created_by.name }}
</p>
@@ -33,18 +33,46 @@
</div>
{{display_message_status}}
{% else %}
<div class="usa-alert usa-alert--success">
<div class="usa-alert__body">
<h2 class="usa-alert__heading">Your text has been sent</h2>
<p class="usa-alert__text">
{{ job.template_name }} - {{ current_service.name }} was sent on {% if job.processing_started %}
{{ job.processing_started|format_datetime_table }} {% else %}
{{ job.created_at|format_datetime_table }} {% endif %} by {{ job.created_by.name }}
</p>
{% if job.processing_started %}
<div class="usa-alert usa-alert--success">
<div class="usa-alert__body">
<h2 class="usa-alert__heading">
Your message is sending
</h2>
<p class="usa-alert__text">
{{ job.template_name }} - {{ current_service.name }}
has been sending since {{job.processing_started| format_datetime_normal}} by {{ job.created_by.name }}
</p>
</div>
</div>
</div>
{% else %}
<div class="usa-alert usa-alert--info">
<div class="usa-alert__body">
<h2 class="usa-alert__heading">
Your message is pending
</h2>
<p class="usa-alert__text">
{{ job.template_name }} - {{ current_service.name }}
has been pending since {{job.created_at|format_datetime_normal}} by {{ job.created_by.name }}
</p>
</div>
</div>
{% endif %}
{{display_message_status}}
{% endif %}
{% elif arrived_from_preview_page_url %}
<div class="usa-alert usa-alert--success">
<div class="usa-alert__body">
<h2 class="usa-alert__heading">
Your message has been sent
</h2>
<p class="usa-alert__text">
{{ job.template_name }} - {{ current_service.name }}
was sent on {{job.processing_started|format_datetime_normal}} by {{ job.created_by.name }}
</p>
</div>
</div>
{{display_message_status}}
{% endif %}
</p>
{% if job.status == 'sending limits exceeded'%}

View File

@@ -0,0 +1,72 @@
<h2 class="line-height-sans-2 margin-bottom-0 margin-top-4">Recent activity</h2>
<div id="activityChartContainer">
<form class="usa-form">
<label class="usa-label" for="options">Account</label>
<select class="usa-select margin-bottom-2" name="options" id="options">
<option value disabled>- Select -</option>
<option value="service" selected>{{ current_service.name }}</option>
<option value="individual">{{ current_user.name }}</option>
</select>
</form>
<div id="activityChart">
<div class="chart-header">
<div class="chart-subtitle">{{ current_service.name }} - last 7 days</div>
<div class="chart-legend" role="region" aria-label="Legend"></div>
</div>
<div class="chart-container" id="weeklyChart"></div>
<table id="weeklyTable" class="usa-sr-only usa-table"></table>
</div>
</div>
<div id="aria-live-account" class="usa-sr-only" aria-live="polite"></div>
<div class="table-container" id="activityContainer" data-currentUserName="{{ current_user.name }}" data-currentServiceId="{{current_service.id}}">
<div id="tableActivity" class="table-overflow-x-auto">
<h2 id="table-heading" class="margin-top-4 margin-bottom-1">Service activity</h2>
<table class="usa-table job-table" id="activity-table">
<caption class="usa-sr-only">Table showing the sent jobs for {{current_service.name}}</caption>
<thead class="table-field-headings">
<tr>
<th scope="col" class="table-field-heading-first" id="jobId">Job ID#</th>
<th data-sortable scope="col" class="table-field-heading" scope="col">Template</th>
<th data-sortable scope="col" class="table-field-heading">Job status</th>
<th data-sortable scope="col" role="columnheader" class="table-field-heading sender-column">Sender
</th>
<th data-sortable scope="col" class="table-field-heading"># of Recipients</th>
</tr>
</thead>
<tbody>
{% if jobs %}
{% for job in jobs %}
<tr id="{{ job.id }}">
<td class="table-field jobid" role="rowheader">
<a class="usa-link" href="{{ url_for('.view_job', service_id=current_service.id, job_id=job.id )}}">
{{ job.id[:8] if job.id else 'Manually entered number' }}
</a>
</td>
<td class="table-field template">{{ job.template_name }}</td>
<td class="table-field time-sent">
{% 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 %}
</td>
<td class="table-field sender sender-column">{{ job.created_by.name }}</td>
<td class="table-field count-of-recipients">{{ job.notification_count }}</td>
</tr>
{% endfor %}
{% else %}
<tr class="table-row">
<td class="table-empty-message" colspan="10">No batched job messages found &thinsp;(messages are
kept for {{ service_data_retention_days }} days).</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>

View File

@@ -6,140 +6,38 @@
{% from "components/ajax-block.html" import ajax_block %}
{% block service_page_title %}
Dashboard
Dashboard
{% endblock %}
{% block maincolumn_content %}
<script type="text/javascript" src="{{ asset_url('js/setTimezone.js') }}"></script>
<script type="text/javascript" src="{{ asset_url('js/setTimezone.js') }}"></script>
<div class="dashboard margin-top-0 margin-bottom-2">
<div class="dashboard margin-top-0 margin-bottom-2">
<h1 class="usa-sr-only">Dashboard</h1>
{% if current_user.has_permissions('manage_templates') and not current_service.all_templates %}
{% include 'views/dashboard/write-first-messages.html' %}
{% endif %}
<h1 class="usa-sr-only">Dashboard</h1>
{% if current_user.has_permissions('manage_templates') and not current_service.all_templates %}
{% include 'views/dashboard/write-first-messages.html' %}
{% endif %}
{{ ajax_block(partials, updates_url, 'upcoming') }}
{{ ajax_block(partials, updates_url, 'upcoming') }}
<h2 class="font-body-2xl line-height-sans-2 margin-top-0">{{ current_service.name }} Dashboard</h2>
<h2 class="font-body-2xl line-height-sans-2 margin-top-0">{{ current_service.name }} Dashboard</h2>
{{ ajax_block(partials, updates_url, 'inbox') }}
{{ ajax_block(partials, updates_url, 'inbox') }}
<div id="totalMessageChartContainer" data-sms-sent="{{ sms_sent }}" data-sms-allowance-remaining="{{ sms_allowance_remaining }}">
<h2 id="chartTitle">Total messages</h2>
<svg id="totalMessageChart"></svg>
<div id="message"></div>
</div>
<div id="totalMessageTable" class="margin-0"></div>
<div id="totalMessageChartContainer" data-sms-sent="{{ sms_sent }}" data-sms-allowance-remaining="{{ sms_allowance_remaining }}">
<h2 id="chartTitle">Total messages</h2>
<svg id="totalMessageChart"></svg>
<div id="message"></div>
</div>
<div id="totalMessageTable" class="margin-0"></div>
<h2 class="line-height-sans-2 margin-bottom-0 margin-top-4">Recent activity</h2>
<div id="activityChartContainer">
<form class="usa-form">
<label class="usa-label" for="options">Account</label>
<select class="usa-select margin-bottom-2" name="options" id="options">
<option value disabled>- Select -</option>
<option value="service" selected>{{ current_service.name }}</option>
<option value="individual">{{ current_user.name }}</option>
</select>
</form>
<div id="activityChart">
<div class="chart-header">
<div class="chart-subtitle">{{ current_service.name }} - last 7 days</div>
<div class="chart-legend" role="region" aria-label="Legend"></div>
</div>
<div class="chart-container" id="weeklyChart"></div>
<table id="weeklyTable" class="usa-sr-only usa-table"></table>
</div>
</div>
<div id="aria-live-account" class="usa-sr-only" aria-live="polite"></div>
{% include 'views/dashboard/activity-table.html' %}
{% if current_user.has_permissions('manage_service') %}{% endif %}
{% if current_user.has_permissions('manage_service') %}{% endif %}
<div class="table-container">
<div id="table1" class="table-overflow-x-auto hidden">
<h2 class="margin-top-4 margin-bottom-1">My activity</h2>
<table class="usa-table job-table">
<caption class="usa-sr-only">Table showing the sent jobs for {{current_user.name}}</caption>
<thead class="table-field-headings">
<tr>
<th scope="col" class="table-field-heading-first" id="jobId"><span>Job ID#</span></th>
<th data-sortable scope="col" class="table-field-heading"><span>Template</span></th>
<th data-sortable scope="col" class="table-field-heading"><span>Job status</span></th>
<th data-sortable scope="col" class="table-field-heading"><span># of Recipients</span></th>
</tr>
</thead>
<tbody>
{% if jobs %}
{% for job in jobs[:5] %}
{% if job.created_by.name == current_user.name %}
{% set notification = job.notifications[0] %}
<tr id="{{ job.job_id }}">
<td class="table-field jobid" role="rowheader">
<a class="usa-link" href="{{ job.view_job_link }}">
{{ job.job_id[:8] if job.job_id else 'Manually entered number' }}
</a>
</td>
<td class="table-field template">{{ job.template_name }}</td>
<td class="table-field time-sent">Sent on
{{ (job.processing_finished if job.processing_finished else job.processing_started
if job.processing_started else job.created_at)|format_datetime_table }}
</td>
<td class="table-field count-of-recipients">{{ job.notification_count }}</td>
</tr>
{% endif %}
{% endfor %}
{% else %}
<tr class="table-row">
<td class="table-empty-message" colspan="10">No batched job messages found &thinsp;(messages are kept for {{ service_data_retention_days }} days).</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
<div id="table2" class="table-overflow-x-auto visible">
<h2 class="margin-top-4 margin-bottom-1">Service activity</h2>
<table class="usa-table job-table">
<caption class="usa-sr-only">Table showing the sent jobs for this service</caption>
<thead class="table-field-headings">
<tr>
<th scope="col" role="columnheader" class="table-field-heading-first" id="jobId"><span>Job ID#</span></th>
<th data-sortable scope="col" role="columnheader" class="table-field-heading"><span>Template</span></th>
<th data-sortable scope="col" role="columnheader" class="table-field-heading"><span>Job status</span></th>
<th data-sortable scope="col" role="columnheader" class="table-field-heading"><span>Sender</span></th>
<th data-sortable scope="col" role="columnheader" class="table-field-heading"><span># of Recipients</span></th>
</tr>
</thead>
<tbody>
{% if jobs %}
{% for job in jobs[:5] %}
{% set notification = job.notifications[0] %}
<tr id="{{ job.job_id }}">
<td class="table-field jobid" role="rowheader">
<a class="usa-link" href="{{ job.view_job_link }}">
{{ job.job_id[:8] if job.job_id else 'Manually entered number' }}
</a>
</td>
<td class="table-field template">{{ job.template_name }}</td>
<td class="table-field time-sent">Sent on
{{ (job.processing_finished if job.processing_finished else job.processing_started
if job.processing_started else job.created_at)|format_datetime_table }}
</td>
<td class="table-field sender">{{ job.created_by.name }}</td>
<td class="table-field count-of-recipients">{{ job.notification_count }}</td>
</tr>
{% endfor %}
{% else %}
<tr class="table-row">
<td class="table-empty-message" colspan="10">No batched job messages found &thinsp;(messages are kept for {{ service_data_retention_days }} days).</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>
{{ ajax_block(partials, updates_url, 'template-statistics') }}
</div>
{{ ajax_block(partials, updates_url, 'template-statistics') }}
</div>
{% endblock %}

View File

@@ -29,11 +29,9 @@
{% call form_wrapper() %}
<div class="grid-row">
<div class="tablet:grid-col-9 mobile-lg:grid-col-12" aria-live="polite" role="alert">
<div class="tablet:grid-col-9 mobile-lg:grid-col-12">
{{ form.name(param_extensions={
"extra_form_group_classes": "margin-bottom-2",
"id": "name",
"required": True,
"hint": {"text": "Your recipients will not see this"}
}) }}
{{ textbox(
@@ -43,8 +41,7 @@
hint=content_hint,
rows=5,
extra_form_group_classes='margin-bottom-1',
placeholder='Edit me! Check out the Personalization section below for details on cool ((stuff)) you can do with your messages!',
required=True
placeholder='Edit me! Check out the Personalization section below for details on cool ((stuff)) you can do with your messages!'
) }}
{% if current_user.platform_admin %}
{{ form.process_type }}

View File

@@ -28,7 +28,7 @@
<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>
<p class="usa-body">See <a class="usa-link" href="{{ url_for('.how_to', _anchor='personalized-content') }}">how to personalize your content</a>.</p>
<h2 class="heading-medium" id="bulk-sending">Bulk sending</h2>
<p class="usa-body">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.</p>

View File

@@ -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") }}
<section class="usa-prose">
<h1>{{page_title}}</h1>

View File

@@ -1,6 +1,6 @@
{% extends "base.html" %}
{% set page_title = "Best Practices" %}
{% set page_title = "Best practices" %}
{% block per_page_title %}
{{page_title}}
@@ -8,7 +8,7 @@
{% block content_column_content %}
<section class="usa-prose">
<h1>Best Practices</h1>
<h1>Best practices</h1>
<p class="font-sans-lg text-base">For texting the public</p>
<p>Effectively reaching your audience and supporting your programs goals starts with strategically planning out what
text messages can help you achieve and how to approach a thoughtful rollout.

View File

@@ -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") }}
<section class="usa-prose">
<h1>{{page_title}}</h1>

View File

@@ -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") }}
<section class="usa-prose">
<h1>{{page_title}}</h1>

View File

@@ -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") }}
<section class="usa-prose">
<h1>{{page_title}}</h1>

View File

@@ -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") }}
<section class="usa-prose">
<h1>{{page_title}}</h1>

View File

@@ -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") }}
<section class="usa-prose">
<h1>{{page_title}}</h1>

View File

@@ -4,11 +4,11 @@
{% from "components/service-link.html" import service_link %}
{% block per_page_title %}
Guidance
How to
{% endblock %}
{% block content_column_content %}
<h1 class="font-body-2xl margin-bottom-3">Guidance</h1>
<h1 class="font-body-2xl margin-bottom-3">How to</h1>
<p>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.</p>
@@ -61,7 +61,7 @@ your recipient to manage their benefits and increase follow-through.</p>
<ol class="list">
<li>Add a placeholder to your content by placing two brackets around the personalized elements.</li>
<li>You can manually enter the personalized content or you can upload a spreadsheet with the details and let Notify do the
work for you. See <a href="#prepare-data">data preparation</a>.</li>
work for you.</li>
</ol>
<h4>Example</h4>
@@ -80,7 +80,7 @@ all or part of the message contingent upon specific criteria associated with the
<ol class="list">
<li>Use two brackets and ?? to define the conditional content.</li>
<li>You can manually enter the conditional content or you can upload a spreadsheet with the personal details and let Notify
do the work for you. See <a href="#prepare-data">data preparation</a>.</li>
do the work for you.</li>
</ol>
<h4>Examples</h4>

View File

@@ -11,7 +11,18 @@
{% block maincolumn_content %}
{{ page_header("Message status") }}
{{ partials['status']|safe }}
{% if not job.processing_finished %}
<div
data-module="update-content"
data-resource="{{ updates_url }}"
data-key="status"
data-form=""
>
{% endif %}
{{ partials['status']|safe }}
{% if not job.processing_finished %}
</div>
{% endif %}
{% if not finished %}
<div
data-module="update-content"

View File

@@ -34,7 +34,7 @@
{% set product_highlights = [
{
"svg_src": "#chat",
"card_heading": "Up to 250,000 messages to use over your first year*",
"card_heading": "Up to 100,000 messages to use over your first year*",
},
{
"svg_src": "#phone",

View File

@@ -37,8 +37,8 @@
data_kwargs={'force-focus': True}
) %}
<div class="grid-row">
<div class="grid-col-12 {% if form.placeholder_value.label.text == 'phone number' %}extra-tracking{% endif %}">
{{ form.placeholder_value(param_extensions={"id": "phone-number"}) }}
<div class="grid-col-12 {% if form.placeholder_value.label.text == 'phone number' %}extra-tracking{% endif %}" aria-live="polite" role="alert">
{{ form.placeholder_value(param_extensions={"classes": ""}) }}
</div>
{% if skip_link or link_to_upload %}
<div class="grid-col-12 margin-top-1">

View File

@@ -13,8 +13,8 @@
<h1 class="font-body-2xl margin-bottom-3">Contact us</h1>
<p>Notify is designed to be easy to use.</p>
<ul class="list list-bullet">
<li>For information on personalization and data preparation, see <a href={{ url_for("main.guidance_index") }}>Guidance</a>.</li>
<li>For help interpreting delivery reports, see <a href={{ url_for("main.message_status") }}>Delivery Status</a>.</li>
<li>For information on personalization, see <a href={{ url_for("main.how_to") }}>How to</a>.</li>
<li>For help interpreting delivery reports, see <a href={{ url_for("main.message_status") }}>Delivery status</a>.</li>
<li>For details on pricing and what counts as a message part, see <a href={{ url_for("main.pricing") }}>Pricing</a>.</li>
</ul>

View File

@@ -90,4 +90,8 @@
{% endif %}
</div>
<!--<div class="">
{{ copy_to_clipboard(template.id, name="Template ID", thing='template ID') }}
</div>-->
{% endblock %}