mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-05-30 11:00:14 -04:00
> When the CSV is missing the header row, we get an error and the user > will see "Sorry, we are experiencing technical difficulties..." > > We should return a better error message for the user. – https://www.pivotaltracker.com/story/show/140668615 This was caused by an attempt to access the `first_recipient` variable before it was assigned. It would only be assigned when there was at least one row in the file. Fixing this means doing two things: - defaulting `first_recipient` to be `None` before looking in the file - adding an error message for when we can’t extract any rows out of the file (which is more nuanced than the file just being completely empty) (There’s a nasty `sort` in the Jinja template because when there are no rows in the file the order of the required column headers is not deterministic.)
242 lines
8.0 KiB
HTML
242 lines
8.0 KiB
HTML
{% extends "withnav_template.html" %}
|
||
{% from "components/banner.html" import banner_wrapper %}
|
||
{% from "components/radios.html" import radio_select %}
|
||
{% from "components/table.html" import list_table, field, text_field, index_field, hidden_field_heading %}
|
||
{% from "components/file-upload.html" import file_upload %}
|
||
{% from "components/page-footer.html" import page_footer %}
|
||
{% from "components/message-count-label.html" import message_count_label %}
|
||
|
||
{% set file_contents_header_id = 'file-preview' %}
|
||
{% macro skip_to_file_contents() %}
|
||
<p class="visually-hidden">
|
||
<a href="#{{ file_contents_header_id }}">Skip to file contents</a>
|
||
</p>
|
||
{% endmacro %}
|
||
|
||
{% block service_page_title %}
|
||
{{ "Error" if errors else "Preview" }}
|
||
{% endblock %}
|
||
|
||
{% block maincolumn_content %}
|
||
|
||
{% if recipients.too_many_rows %}
|
||
|
||
<div class="bottom-gutter">
|
||
{% call banner_wrapper(type='dangerous') %}
|
||
<h1 class='banner-title'>
|
||
Your file has too many rows
|
||
</h1>
|
||
<p>
|
||
Notify can process up to
|
||
{{ "{:,}".format(recipients.max_rows) }} rows at once. Your
|
||
file has {{ "{:,}".format(recipients|length) }} rows.
|
||
</p>
|
||
{{ skip_to_file_contents() }}
|
||
{% endcall %}
|
||
</div>
|
||
|
||
{% elif not count_of_recipients %}
|
||
|
||
<div class="bottom-gutter">
|
||
{% call banner_wrapper(type='dangerous') %}
|
||
<h1 class='banner-title'>
|
||
Your file is missing some rows
|
||
</h1>
|
||
<p>
|
||
It needs at least one row of data, and {{ recipients.missing_column_headers | sort() | formatted_list(
|
||
prefix='a column called',
|
||
prefix_plural='columns called'
|
||
) }}.
|
||
</p>
|
||
{{ skip_to_file_contents() }}
|
||
{% endcall %}
|
||
</div>
|
||
|
||
{% elif not recipients.has_recipient_columns %}
|
||
|
||
<div class="bottom-gutter">
|
||
{% call banner_wrapper(type='dangerous') %}
|
||
<h1 class='banner-title'>
|
||
Your file needs to have {{ recipients.recipient_column_headers | formatted_list(
|
||
prefix='a column called',
|
||
prefix_plural='columns called'
|
||
) }}
|
||
</h1>
|
||
<p>
|
||
Your file has {{ recipients.column_headers | formatted_list(
|
||
prefix='one column, called ',
|
||
prefix_plural='columns called '
|
||
) }}.
|
||
</p>
|
||
{{ skip_to_file_contents() }}
|
||
{% endcall %}
|
||
</div>
|
||
|
||
{% elif recipients.missing_column_headers %}
|
||
|
||
<div class="bottom-gutter">
|
||
{% call banner_wrapper(type='dangerous') %}
|
||
<h1 class='banner-title'>
|
||
The columns in your file need to match the double brackets in
|
||
your template
|
||
</h1>
|
||
<p>
|
||
Your file has {{ recipients.column_headers | formatted_list(
|
||
prefix='one column, called ',
|
||
prefix_plural='columns called '
|
||
) }}.
|
||
</p>
|
||
<p>
|
||
It doesn’t have {{ recipients.missing_column_headers | formatted_list(
|
||
conjunction='or',
|
||
prefix='a column called ',
|
||
prefix_plural='columns called '
|
||
) }}.
|
||
</p>
|
||
{{ skip_to_file_contents() }}
|
||
{% endcall %}
|
||
</div>
|
||
|
||
{% elif row_errors %}
|
||
|
||
<div class="bottom-gutter">
|
||
{% call banner_wrapper(type='dangerous') %}
|
||
{% if row_errors|length == 1 %}
|
||
<h1 class='banner-title'>
|
||
There is a problem with your data
|
||
</h1>
|
||
<p>
|
||
You need to {{ row_errors[0] }}
|
||
</p>
|
||
{% else %}
|
||
<h1 class='banner-title'>
|
||
There are some problems with your data
|
||
</h1>
|
||
<p>
|
||
You need to:
|
||
</p>
|
||
<ul class="list-bullet">
|
||
{% for error in row_errors %}
|
||
<li>{{ error }}</li>
|
||
{% endfor %}
|
||
</ul>
|
||
{% endif %}
|
||
{{ skip_to_file_contents() }}
|
||
{% endcall %}
|
||
</div>
|
||
|
||
{% elif not recipients.allowed_to_send_to %}
|
||
|
||
<div class="bottom-gutter">
|
||
{% call banner_wrapper(type='dangerous') %}
|
||
<h1 class='banner-title'>
|
||
You can’t send to
|
||
{{ 'this' if count_of_recipients == 1 else 'these' }}
|
||
{{ recipients.recipient_column_headers[0] }}
|
||
{%- if count_of_recipients != 1 -%}
|
||
{{ 'es' if 'email address' == recipients.recipient_column_headers[0] else 's' }}
|
||
{%- endif %}
|
||
</h1>
|
||
<p>
|
||
In <a href="{{ url_for('.trial_mode') }}">trial mode</a> you can only
|
||
send to yourself and members of your team
|
||
</p>
|
||
{{ skip_to_file_contents() }}
|
||
{% endcall %}
|
||
</div>
|
||
|
||
{% elif recipients.more_rows_than_can_send %}
|
||
{% include "partials/check/too-many-messages.html" %}
|
||
{% else %}
|
||
|
||
<h1 class="heading-large">
|
||
Preview
|
||
</h1>
|
||
{{ skip_to_file_contents() }}
|
||
|
||
{% endif %}
|
||
|
||
{{ template|string }}
|
||
|
||
<div class="bottom-gutter-3-2">
|
||
{% if errors %}
|
||
{% if request.args.from_test %}
|
||
<a href="{{ back_link }}" class="page-footer-back-link">Back</a>
|
||
{% else %}
|
||
{{file_upload(form.file, button_text='Re-upload your file')}}
|
||
{% endif %}
|
||
{% else %}
|
||
<form method="post" enctype="multipart/form-data" action="{{url_for('main.start_job', service_id=current_service.id, upload_id=upload_id)}}" class='page-footer'>
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||
<input type="hidden" name="help" value="{{ '3' if help else 0 }}" />
|
||
{% if choose_time_form %}
|
||
{{ radio_select(
|
||
choose_time_form.scheduled_for,
|
||
wrapping_class='bottom-gutter-2-3'
|
||
) }}
|
||
{% endif %}
|
||
<input type="submit" class="button" value="Send {{ count_of_recipients }} {{ message_count_label(count_of_recipients, template.template_type, suffix='') }}" />
|
||
<a href="{{ back_link }}" class="page-footer-back-link">Back</a>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
|
||
<h2 class="heading-medium" id="{{ file_contents_header_id }}">{{ original_file_name }}</h2>
|
||
|
||
{% call(item, row_number) list_table(
|
||
recipients.initial_annotated_rows_with_errors if row_errors and not recipients.missing_column_headers else recipients.initial_annotated_rows,
|
||
caption=original_file_name,
|
||
caption_visible=False,
|
||
field_headings=[
|
||
'<span class="visually-hidden">Row in file</span><span aria-hidden="true">1</span>'|safe
|
||
] + recipients.column_headers
|
||
) %}
|
||
{{ index_field(item.index + 2) }}
|
||
{% for column in recipients.column_headers %}
|
||
{% if item['columns'][column].error and not recipients.missing_column_headers %}
|
||
{% call field() %}
|
||
<span class="table-field-error">
|
||
<span class="table-field-error-label">{{ item['columns'][column].error }}</span>
|
||
{{ item['columns'][column].data if item['columns'][column].data != None }}
|
||
</span>
|
||
{% endcall %}
|
||
{% elif item['columns'][column].ignore %}
|
||
{% call field(status='default') %}
|
||
{{ item['columns'][column].data if item['columns'][column].data != None }}
|
||
{% endcall %}
|
||
{% else %}
|
||
{% call field() %}
|
||
{{ item['columns'][column].data if item['columns'][column].data != None }}
|
||
{% endcall %}
|
||
{% endif %}
|
||
{% endfor %}
|
||
{% if item['columns'].get(None) %}
|
||
{% for column in item['columns'][None].data %}
|
||
{% call field(status='default') %}
|
||
{{ column }}
|
||
{% endcall %}
|
||
{% endfor %}
|
||
{% endif %}
|
||
{% endcall %}
|
||
|
||
|
||
{% if recipients.too_many_rows %}
|
||
<p class="table-show-more-link">
|
||
Can’t show the contents of this file
|
||
</p>
|
||
{% elif count_of_displayed_recipients < count_of_recipients %}
|
||
<p class="table-show-more-link">
|
||
{% if row_errors and not recipients.missing_column_headers %}
|
||
Only showing the first {{ count_of_displayed_recipients }} rows with errors
|
||
{% else %}
|
||
Only showing the first {{ count_of_displayed_recipients }} rows
|
||
{% endif %}
|
||
</p>
|
||
{% elif row_errors and not recipients.missing_column_headers %}
|
||
<p class="table-show-more-link">
|
||
Only showing rows with errors
|
||
</p>
|
||
{% endif %}
|
||
|
||
{% endblock %}
|