diff --git a/app/assets/javascripts/errorTracking.js b/app/assets/javascripts/errorTracking.js
new file mode 100644
index 000000000..3b7053841
--- /dev/null
+++ b/app/assets/javascripts/errorTracking.js
@@ -0,0 +1,22 @@
+(function(Modules) {
+ "use strict";
+
+ Modules.TrackError = function() {
+
+ this.start = function(component) {
+
+ if (!ga) return;
+
+ ga(
+ 'send',
+ 'event',
+ 'Error',
+ $(component).data('error-type'),
+ $(component).data('error-label')
+ );
+
+ };
+
+ };
+
+})(window.GOVUK.Modules);
diff --git a/app/main/views/send.py b/app/main/views/send.py
index 8b72c3b9a..ba92533d4 100644
--- a/app/main/views/send.py
+++ b/app/main/views/send.py
@@ -447,10 +447,24 @@ def _check_messages(service_id, template_type, upload_id, letters_as_pdf=False):
@login_required
@user_has_permissions('send_texts', 'send_emails', 'send_letters')
def check_messages(service_id, template_type, upload_id):
- return render_template(
- 'views/check.html',
- **_check_messages(service_id, template_type, upload_id)
- )
+
+ data = _check_messages(service_id, template_type, upload_id)
+
+ if (
+ data['recipients'].too_many_rows or
+ not data['count_of_recipients'] or
+ not data['recipients'].has_recipient_columns or
+ data['recipients'].missing_column_headers
+ ):
+ return render_template('views/check/column-errors.html', **data)
+
+ if data['row_errors']:
+ return render_template('views/check/row-errors.html', **data)
+
+ if data['errors']:
+ return render_template('views/check/column-errors.html', **data)
+
+ return render_template('views/check/ok.html', **data)
@main.route("/services///check/.", methods=['GET'])
diff --git a/app/templates/partials/check/not-allowed-to-send-to.html b/app/templates/partials/check/not-allowed-to-send-to.html
index 5d2f001fb..4d445e9c6 100644
--- a/app/templates/partials/check/not-allowed-to-send-to.html
+++ b/app/templates/partials/check/not-allowed-to-send-to.html
@@ -1,25 +1,12 @@
-{% from "components/banner.html" import banner_wrapper %}
-
-{% macro skip_to_file_contents() %}
-
- Skip to file contents
-
-{% endmacro %}
-
-
- {% call banner_wrapper(type='dangerous') %}
-
- You can’t send to
- {{ 'this' if count_of_recipients == 1 else 'these' }}
- {{ template_type_label }}
- {%- if count_of_recipients != 1 -%}
- {{ 'es' if 'email address' == template_type_label else 's' }}
- {%- endif %}
-
-
- In trial mode you can only
- send to yourself and members of your team
-
- {{ skip_to_file_contents() }}
- {% endcall %}
-
+
+ You can’t send to
+ {{ 'this' if count_of_recipients == 1 else 'these' }}
+ {{ template_type_label }}
+ {%- if count_of_recipients != 1 -%}
+ {{ 'es' if 'email address' == template_type_label else 's' }}
+ {%- endif %}
+
+
+ In trial mode you can only
+ send to yourself and members of your team
+
diff --git a/app/templates/partials/check/too-many-messages.html b/app/templates/partials/check/too-many-messages.html
index 217ebad33..fd16b0534 100644
--- a/app/templates/partials/check/too-many-messages.html
+++ b/app/templates/partials/check/too-many-messages.html
@@ -1,46 +1,40 @@
-{% from "components/banner.html" import banner_wrapper %}
-
-
- {% call banner_wrapper(type='dangerous') %}
-
- {% if original_file_name %}
- Too many recipients
- {% else %}
- Daily limit reached
- {% endif %}
-
-
- You can only send {{ current_service.message_limit }} messages per day
- {%- if current_service.restricted %}
- in trial mode
- {%- endif -%}
- .
-
- {% if original_file_name %}
-
- {% if current_service.message_limit != remaining_messages %}
- You can still send {{ remaining_messages }} messages today, but
- {% endif %}
- ‘{{ original_file_name }}’ contains
- {{ count_of_recipients }}
- {% if count_of_recipients == 1 -%}
- {%- if template.template_type == 'email' -%}
- email address
- {%- elif template.template_type == 'sms' -%}
- phone number
- {%- elif template.template_type == 'letter' -%}
- address
- {%- endif -%}
- {%- else -%}
- {%- if template.template_type == 'email' -%}
- email addresses
- {%- elif template.template_type == 'sms' -%}
- phone numbers
- {%- elif template.template_type == 'letter' -%}
- addresses
- {%- endif -%}
- {%- endif -%}.
-
+
+ {% if original_file_name %}
+ Too many recipients
+ {% else %}
+ Daily limit reached
+ {% endif %}
+
+
+ You can only send {{ current_service.message_limit }} messages per day
+ {%- if current_service.restricted %}
+ in trial mode
+ {%- endif -%}
+ .
+
+{% if original_file_name %}
+
+ {% if current_service.message_limit != remaining_messages %}
+ You can still send {{ remaining_messages }} messages today, but
{% endif %}
- {% endcall %}
-
+ ‘{{ original_file_name }}’ contains
+ {{ count_of_recipients }}
+ {% if count_of_recipients == 1 -%}
+ {%- if template.template_type == 'email' -%}
+ email address
+ {%- elif template.template_type == 'sms' -%}
+ phone number
+ {%- elif template.template_type == 'letter' -%}
+ address
+ {%- endif -%}
+ {%- else -%}
+ {%- if template.template_type == 'email' -%}
+ email addresses
+ {%- elif template.template_type == 'sms' -%}
+ phone numbers
+ {%- elif template.template_type == 'letter' -%}
+ addresses
+ {%- endif -%}
+ {%- endif -%}.
+
+{% endif %}
diff --git a/app/templates/views/check.html b/app/templates/views/check/column-errors.html
similarity index 55%
rename from app/templates/views/check.html
rename to app/templates/views/check/column-errors.html
index ebb207edd..f8407792f 100644
--- a/app/templates/views/check.html
+++ b/app/templates/views/check/column-errors.html
@@ -14,16 +14,17 @@
{% endmacro %}
{% block service_page_title %}
- {{ "Error" if errors else "Preview of {}".format(template.name) }}
+ Error
{% endblock %}
{% block maincolumn_content %}
- {% if recipients.too_many_rows %}
+
+ {% call banner_wrapper(type='dangerous') %}
-
- {% call banner_wrapper(type='dangerous') %}
-
+ {% if recipients.too_many_rows %}
+
+
Your file has too many rows
@@ -31,15 +32,10 @@
{{ "{:,}".format(recipients.max_rows) }} rows at once. Your
file has {{ "{:,}".format(recipients|length) }} rows.
- {{ skip_to_file_contents() }}
- {% endcall %}
-
- {% elif not count_of_recipients %}
+ {% elif not count_of_recipients %}
-
- {% call banner_wrapper(type='dangerous') %}
-
+
Your file is missing some rows
@@ -48,15 +44,10 @@
prefix_plural='columns called'
) }}.
- {{ skip_to_file_contents() }}
- {% endcall %}
-
- {% elif not recipients.has_recipient_columns %}
+ {% elif not recipients.has_recipient_columns %}
-
- {% call banner_wrapper(type='dangerous') %}
-
+
Your file needs {{ recipients.recipient_column_headers | formatted_list(
prefix='a column called',
prefix_plural='columns called'
@@ -68,15 +59,10 @@
prefix_plural='columns called '
) }}.
- {{ skip_to_file_contents() }}
- {% endcall %}
-
- {% elif recipients.missing_column_headers %}
+ {% elif recipients.missing_column_headers %}
-
- {% call banner_wrapper(type='dangerous') %}
-
+
The columns in your file need to match the double brackets in
your template
@@ -87,85 +73,29 @@
prefix_plural='columns called '
) }}.
- {{ skip_to_file_contents() }}
- {% endcall %}
-
- {% elif row_errors %}
+ {% elif not recipients.allowed_to_send_to %}
+ {% with
+ count_of_recipients=count_of_recipients,
+ template_type_label=recipients.recipient_column_headers[0]
+ %}
+ {% include "partials/check/not-allowed-to-send-to.html" %}
+ {% endwith %}
+ {% elif recipients.more_rows_than_can_send %}
+ {% include "partials/check/too-many-messages.html" %}
+ {% endif %}
-
- {% call banner_wrapper(type='dangerous') %}
- {% if row_errors|length == 1 %}
-
- There is a problem with your data
-
-
- You need to {{ row_errors[0] }}
-
- {% else %}
-
- There are some problems with your data
-
-
- You need to:
-
-
- {% for error in row_errors %}
- - {{ error }}
- {% endfor %}
-
- {% endif %}
- {{ skip_to_file_contents() }}
- {% endcall %}
-
+ {{ skip_to_file_contents() }}
- {% elif not recipients.allowed_to_send_to %}
- {% with
- count_of_recipients=count_of_recipients,
- template_type_label=recipients.recipient_column_headers[0]
- %}
- {% include "partials/check/not-allowed-to-send-to.html" %}
- {% endwith %}
- {% elif recipients.more_rows_than_can_send %}
- {% include "partials/check/too-many-messages.html" %}
- {% else %}
-
-
- Preview of {{ template.name }}
-
- {{ skip_to_file_contents() }}
-
- {% endif %}
-
- {% if not errors %}
- {{ template|string }}
- {% endif %}
+ {% endcall %}
+
- {% if errors %}
{% if request.args.from_test %}
{% else %}
{{file_upload(form.file, button_text='Re-upload your file')}}
{% endif %}
- {% else %}
-
- {% endif %}
{% if not request.args.from_test %}
@@ -177,7 +107,7 @@
caption=original_file_name,
caption_visible=False,
field_headings=[
- 'Row in file1'.format("table-field-invisible-error" if errors else "")|safe
+ 'Row in file1'|safe
] + recipients.column_headers
) %}
{% call index_field() %}
@@ -227,9 +157,7 @@
{% endif %}
- {% if errors %}
- Preview of {{ template.name }}
- {{ template|string }}
- {% endif %}
+ Preview of {{ template.name }}
+ {{ template|string }}
{% endblock %}
diff --git a/app/templates/views/check/ok.html b/app/templates/views/check/ok.html
new file mode 100644
index 000000000..affa5a4ff
--- /dev/null
+++ b/app/templates/views/check/ok.html
@@ -0,0 +1,91 @@
+{% 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() %}
+
+ Skip to file contents
+
+{% endmacro %}
+
+{% block service_page_title %}
+ {{ "Preview of {}".format(template.name) }}
+{% endblock %}
+
+{% block maincolumn_content %}
+
+
+ Preview of {{ template.name }}
+
+ {{ skip_to_file_contents() }}
+
+ {{ template|string }}
+
+
+
+
+
+ {% if not request.args.from_test %}
+
+
+
+ {% 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=[
+ 'Row in file1'|safe
+ ] + recipients.column_headers
+ ) %}
+ {% call index_field() %}
+
+ {{ item.index + 2 }}
+
+ {% endcall %}
+ {% for column in recipients.column_headers %}
+ {% if item['columns'][column].ignore %}
+ {{ text_field(item['columns'][column].data or '', status='default') }}
+ {% else %}
+ {{ text_field(item['columns'][column].data or '') }}
+ {% endif %}
+ {% endfor %}
+ {% if item['columns'].get(None) %}
+ {% for column in item['columns'][None].data %}
+ {{ text_field(column, status='default') }}
+ {% endfor %}
+ {% endif %}
+ {% endcall %}
+
+ {% endif %}
+
+ {% if count_of_displayed_recipients < count_of_recipients %}
+
+ {% 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 %}
+
+ {% endif %}
+
+{% endblock %}
diff --git a/app/templates/views/check/row-errors.html b/app/templates/views/check/row-errors.html
new file mode 100644
index 000000000..ce470bcd8
--- /dev/null
+++ b/app/templates/views/check/row-errors.html
@@ -0,0 +1,113 @@
+{% 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() %}
+
+ Skip to file contents
+
+{% endmacro %}
+
+{% block service_page_title %}
+ Error
+{% endblock %}
+
+{% block maincolumn_content %}
+
+
+ {% call banner_wrapper(type='dangerous') %}
+ {% if row_errors|length == 1 %}
+
+ There is a problem with your data
+
+
+ You need to {{ row_errors[0] }}
+
+ {% else %}
+
+ There are some problems with your data
+
+
+ You need to:
+
+
+ {% for error in row_errors %}
+ - {{ error }}
+ {% endfor %}
+
+ {% endif %}
+ {{ skip_to_file_contents() }}
+ {% endcall %}
+
+
+
+ {% if request.args.from_test %}
+
+ {% else %}
+ {{file_upload(form.file, button_text='Re-upload your file')}}
+ {% endif %}
+
+
+ {% if not request.args.from_test %}
+
+
+
+ {% 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=[
+ 'Row in file1'|safe
+ ] + recipients.column_headers
+ ) %}
+ {% call index_field() %}
+
+ {{ item.index + 2 }}
+
+ {% endcall %}
+ {% for column in recipients.column_headers %}
+ {% if item['columns'][column].error and not recipients.missing_column_headers %}
+ {% call field() %}
+
+ {{ item['columns'][column].error }}
+ {{ item['columns'][column].data if item['columns'][column].data != None }}
+
+ {% endcall %}
+ {% elif item['columns'][column].ignore %}
+ {{ text_field(item['columns'][column].data or '', status='default') }}
+ {% else %}
+ {{ text_field(item['columns'][column].data or '') }}
+ {% endif %}
+ {% endfor %}
+ {% if item['columns'].get(None) %}
+ {% for column in item['columns'][None].data %}
+ {{ text_field(column, status='default') }}
+ {% endfor %}
+ {% endif %}
+ {% endcall %}
+
+ {% endif %}
+
+ {% if count_of_displayed_recipients < count_of_recipients %}
+
+ {% 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 %}
+
+ {% elif row_errors and not recipients.missing_column_headers %}
+
+ Only showing rows with errors
+
+ {% endif %}
+
+ Preview of {{ template.name }}
+ {{ template|string }}
+
+{% endblock %}
diff --git a/gulpfile.babel.js b/gulpfile.babel.js
index a4d044fba..26dd6c96b 100644
--- a/gulpfile.babel.js
+++ b/gulpfile.babel.js
@@ -66,6 +66,7 @@ gulp.task('javascripts', () => gulp
paths.src + 'javascripts/updateContent.js',
paths.src + 'javascripts/listEntry.js',
paths.src + 'javascripts/liveSearch.js',
+ paths.src + 'javascripts/errorTracking.js',
paths.src + 'javascripts/main.js'
])
.pipe(plugins.prettyerror())