From 3ac65b122c50510576cd22eb3c2547fe1433885e Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Fri, 2 Feb 2024 14:52:48 -0800 Subject: [PATCH 01/27] inital preview page --- app/main/views/send.py | 55 ++++++++++++++- app/templates/views/check/ok.html | 79 +++++++++++---------- app/templates/views/check/preview.html | 96 ++++++++++++++++++++++++++ 3 files changed, 188 insertions(+), 42 deletions(-) create mode 100644 app/templates/views/check/preview.html diff --git a/app/main/views/send.py b/app/main/views/send.py index 91e9814af..1d1304dc4 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -13,6 +13,7 @@ from notifications_utils.recipients import RecipientCSV, first_column_headings from notifications_utils.sanitise_text import SanitiseASCII from xlrd.biffh import XLRDError from xlrd.xldate import XLDateError +from pprint import pprint from app import ( current_service, @@ -563,6 +564,7 @@ def _check_messages(service_id, template_id, upload_id, preview_row): sent_previously=job_api_client.has_sent_previously( service_id, template.id, db_template["version"], original_file_name ), + template_id=template_id ) @@ -606,17 +608,18 @@ def check_messages(service_id, template_id, upload_id, row_index=2): metadata_kwargs["sender_id"] = session["sender_id"] set_metadata_on_csv_upload(service_id, upload_id, **metadata_kwargs) - + session['scheduled_for']=request.form.get("scheduled_for", "") return render_template("views/check/ok.html", **data) @main.route("/services//start-job/", methods=["POST"]) @user_has_permissions("send_messages", restrict_admin_usage=True) def start_job(service_id, upload_id): + scheduled_for = session.pop('scheduled_for', None) job_api_client.create_job( upload_id, service_id, - scheduled_for=request.form.get("scheduled_for", ""), + scheduled_for=scheduled_for, ) session.pop("sender_id", None) @@ -630,6 +633,54 @@ def start_job(service_id, upload_id): ) +@main.route( + "/services///check//preview", + methods=["POST"], +) +@main.route( + "/services///check//row-/preview", + methods=["POST"], +) +@main.route("/services//preview-job/", methods=["POST"]) +@user_has_permissions("send_messages", restrict_admin_usage=True) +def preview_job(service_id, template_id, upload_id, row_index=2): + # Store form data in session temporarily + session['scheduled_for'] = request.form.get('scheduled_for', 'Not specified') + # session.pop("sender_id", None) + data = _check_messages(service_id, template_id, upload_id, row_index) + data["allowed_file_extensions"] = Spreadsheet.ALLOWED_FILE_EXTENSIONS + + if ( + data["recipients"].too_many_rows + or not data["count_of_recipients"] + or not data["recipients"].has_recipient_columns + or data["recipients"].duplicate_recipient_column_headers + or data["recipients"].missing_column_headers + or data["sent_previously"] + ): + 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) + + metadata_kwargs = { + "notification_count": data["count_of_recipients"], + "template_id": template_id, + "valid": True, + "original_file_name": data.get("original_file_name", ""), + } + + if session.get("sender_id"): + metadata_kwargs["sender_id"] = session["sender_id"] + + set_metadata_on_csv_upload(service_id, upload_id, **metadata_kwargs) + + return render_template('views/check/preview.html', data=session['scheduled_for'], **data) + + def fields_to_fill_in(template, prefill_current_user=False): if not prefill_current_user: return first_column_headings[template.template_type] + list( diff --git a/app/templates/views/check/ok.html b/app/templates/views/check/ok.html index b795a5971..6fc96f73b 100644 --- a/app/templates/views/check/ok.html +++ b/app/templates/views/check/ok.html @@ -19,11 +19,11 @@ {% block maincolumn_content %} - {{ page_header('Preview of {}'.format(template.name)) }} + {{ page_header('Select delivery time') }} {{ template|string }}
-
- {% if not request.args.from_test %} - -

{{ original_file_name }}

- -
- {% call(item, row_number) list_table( - recipients.displayed_rows, - caption=original_file_name, - caption_visible=False, - field_headings=[ - 'Row in file'|safe - ] + recipients.column_headers - ) %} - {% call index_field() %} - - {% if (item.index + 2) == preview_row %} - {{ item.index + 2 }} - {% else %} - {{ item.index + 2 }} - {% endif %} - - {% endcall %} - {% for column in recipients.column_headers %} - {% if item[column].ignore %} - {{ text_field(item[column].data or '', status='default') }} + - {% endif %} - - {% if count_of_displayed_recipients < count_of_recipients %} + {% endblock %} diff --git a/app/templates/views/check/preview.html b/app/templates/views/check/preview.html new file mode 100644 index 000000000..14b9166f3 --- /dev/null +++ b/app/templates/views/check/preview.html @@ -0,0 +1,96 @@ +{% extends "withnav_template.html" %} +{% from "components/banner.html" import banner_wrapper %} +{% from "components/table.html" import list_table, field, text_field, index_field, hidden_field_heading %} +{% from "components/page-header.html" import page_header %} +{% from "components/components/button/macro.njk" import usaButton %} +{% from "components/components/skip-link/macro.njk" import usaSkipLink %} +{% from "components/components/back-link/macro.njk" import usaBackLink %} + +{% set file_contents_header_id = 'file-preview' %} + +{% block service_page_title %} + {{ "Preview of {}".format(template.name) }} +{% endblock %} + + +{% block backLink %} + {{ usaBackLink({ "href": back_link }) }} +{% endblock %} + +{% block maincolumn_content %} + + {{ page_header('Send messages') }} +

Message

+ {{ template|string }} +
+ +
+ + + + +{% endblock %} From c073d2efacdd6292a1572d2919401153a1b6f3df Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Fri, 2 Feb 2024 16:14:50 -0800 Subject: [PATCH 02/27] revising message preview --- app/main/views/send.py | 7 +------ app/templates/views/check/preview.html | 4 ++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/main/views/send.py b/app/main/views/send.py index 1d1304dc4..6c014b102 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -637,11 +637,6 @@ def start_job(service_id, upload_id): "/services///check//preview", methods=["POST"], ) -@main.route( - "/services///check//row-/preview", - methods=["POST"], -) -@main.route("/services//preview-job/", methods=["POST"]) @user_has_permissions("send_messages", restrict_admin_usage=True) def preview_job(service_id, template_id, upload_id, row_index=2): # Store form data in session temporarily @@ -678,7 +673,7 @@ def preview_job(service_id, template_id, upload_id, row_index=2): set_metadata_on_csv_upload(service_id, upload_id, **metadata_kwargs) - return render_template('views/check/preview.html', data=session['scheduled_for'], **data) + return render_template('views/check/preview.html', data=session['scheduled_for'], **data, metadata_kwargs=metadata_kwargs) def fields_to_fill_in(template, prefill_current_user=False): diff --git a/app/templates/views/check/preview.html b/app/templates/views/check/preview.html index 14b9166f3..1c07bffc6 100644 --- a/app/templates/views/check/preview.html +++ b/app/templates/views/check/preview.html @@ -21,6 +21,10 @@ {{ page_header('Send messages') }}

Message

+ {% if data %} +

Time: {{data | format_datetime_short_america}}

+ {% endif %} +

File: {{metadata_kwargs.original_file_name}}

{{ template|string }}
- - - {% endblock %} diff --git a/app/templates/views/check/preview.html b/app/templates/views/check/preview.html index 1c07bffc6..c7b303a8a 100644 --- a/app/templates/views/check/preview.html +++ b/app/templates/views/check/preview.html @@ -14,35 +14,23 @@ {% block backLink %} - {{ usaBackLink({ "href": back_link }) }} + {{ usaBackLink({ "href": back_link_from_preview }) }} {% endblock %} {% block maincolumn_content %} - {{ page_header('Send messages') }} + {{ page_header('Preview') }}

Message

- {% if data %} -

Time: {{data | format_datetime_short_america}}

+ {% if scheduled_for %} +

Time: {{scheduled_for}}

{% endif %} -

File: {{metadata_kwargs.original_file_name}}

+

File: {{original_file_name}}

{{ template|string }}
- - - - {% endblock %} diff --git a/app/templates/views/notifications/check.html b/app/templates/views/notifications/check.html index 5bc970f9b..fec77f779 100644 --- a/app/templates/views/notifications/check.html +++ b/app/templates/views/notifications/check.html @@ -40,17 +40,16 @@ {% endcall %}
{% else %} - {{ page_header('Preview of ‘{}’'.format(template.name)) }} + {{ page_header('Select delivery time') }} {% endif %} {{ template|string }}
diff --git a/app/templates/views/notifications/preview.html b/app/templates/views/notifications/preview.html new file mode 100644 index 000000000..868caefd3 --- /dev/null +++ b/app/templates/views/notifications/preview.html @@ -0,0 +1,65 @@ +{% extends "withnav_template.html" %} +{% from "components/banner.html" import banner_wrapper %} +{% from "components/page-header.html" import page_header %} +{% from "components/components/back-link/macro.njk" import usaBackLink %} +{% from "components/components/button/macro.njk" import usaButton %} + +{% block service_page_title %} + {{ "Error" if error else "Preview of ‘{}’".format(template.name) }} +{% endblock %} + +{% block backLink %} + {{ usaBackLink({ "href": back_link_from_preview }) }} +{% endblock %} + +{% block maincolumn_content %} + {% if error == 'not-allowed-to-send-to' %} +
+ {% call banner_wrapper(type='dangerous') %} + {% with + count_of_recipients=1, + template_type_label=( + 'phone number' if template.template_type == 'sms' else 'email address' + ) + %} + {% include "partials/check/not-allowed-to-send-to.html" %} + {% endwith %} + {% endcall %} +
+ {% elif error == 'too-many-messages' %} +
+ {% call banner_wrapper(type='dangerous') %} + {% include "partials/check/too-many-messages.html" %} + {% endcall %} +
+ {% elif error == 'message-too-long' %} + {# the only row_errors we can get when sending one off messages is that the message is too long #} +
+ {% call banner_wrapper(type='dangerous') %} + {% include "partials/check/message-too-long.html" %} + {% endcall %} +
+ {% else %} + {{ page_header('Preview of ‘{}’'.format(template.name)) }} + {% endif %} + + {{ template|string }} + +
+ +
+ +{% endblock %} From 8eb329b444bc01c00171fb4af3829615d46f07c5 Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 6 Feb 2024 16:42:11 -0800 Subject: [PATCH 04/27] removing comments --- app/main/views/send.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/main/views/send.py b/app/main/views/send.py index a07a9009e..59d3ff386 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -13,7 +13,6 @@ from notifications_utils.recipients import RecipientCSV, first_column_headings from notifications_utils.sanitise_text import SanitiseASCII from xlrd.biffh import XLRDError from xlrd.xldate import XLDateError -from pprint import pprint from app import ( current_service, From 15105bf5061ba46d490f6549e1700dd27be8091f Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 6 Feb 2024 17:06:18 -0800 Subject: [PATCH 05/27] fixed style checks --- app/main/views/send.py | 7 ++++--- app/templates/views/check/preview.html | 3 +-- app/templates/views/notifications/preview.html | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/main/views/send.py b/app/main/views/send.py index 59d3ff386..bc527ae10 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -614,7 +614,7 @@ def check_messages(service_id, template_id, upload_id, row_index=2): metadata_kwargs["sender_id"] = session["sender_id"] set_metadata_on_csv_upload(service_id, upload_id, **metadata_kwargs) - session['scheduled_for']=request.form.get("scheduled_for", "") + session['scheduled_for'] = request.form.get("scheduled_for", "") return render_template("views/check/ok.html", **data) @@ -644,7 +644,8 @@ def preview_job(service_id, template_id, upload_id, row_index=2): return render_template("views/check/column-errors.html", **data) return render_template('views/check/preview.html', scheduled_for=session['scheduled_for'], **data, -) + ) + @main.route("/services//start-job/", methods=["POST"]) @user_has_permissions("send_messages", restrict_admin_usage=True) @@ -720,7 +721,6 @@ def get_back_link(service_id, template, step_index, placeholders=None, preview=F template_id=template.id, ) - if step_index == 0: if should_skip_template_page(template._template): return url_for( @@ -871,6 +871,7 @@ def get_template_error_dict(exception): "original_file_name": False, } + @main.route( "/services//template//notification/check/preview", methods=["POST"], diff --git a/app/templates/views/check/preview.html b/app/templates/views/check/preview.html index c7b303a8a..caab43cad 100644 --- a/app/templates/views/check/preview.html +++ b/app/templates/views/check/preview.html @@ -63,8 +63,7 @@ {% endcall %}
{% endif %} - +

This message will be delivered to 400 phone numbers and will use a total of 800 message parts, leaving Washington DSHS with 249,200 message parts remaining.

Does everything look good?

{% set button_text %} Send diff --git a/app/templates/views/notifications/preview.html b/app/templates/views/notifications/preview.html index 868caefd3..dd009fdcb 100644 --- a/app/templates/views/notifications/preview.html +++ b/app/templates/views/notifications/preview.html @@ -53,6 +53,8 @@ help='3' if help else 0 )}}" class='page-footer'> +

This message will be delivered to 400 phone numbers and will use a total of 800 message parts, leaving Washington DSHS with 249,200 message parts remaining.

+

Does everything look good?

{% if not error %} {% set button_text %} Send From fbf902e1684c1b645249ff8fd34e4a52740bdbe6 Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 6 Feb 2024 17:14:46 -0800 Subject: [PATCH 06/27] fixed style checks --- app/main/views/send.py | 3 +-- app/templates/views/check/preview.html | 2 +- app/templates/views/notifications/preview.html | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/main/views/send.py b/app/main/views/send.py index bc527ae10..d81eca83d 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -643,8 +643,7 @@ def preview_job(service_id, template_id, upload_id, row_index=2): if data["errors"]: return render_template("views/check/column-errors.html", **data) - return render_template('views/check/preview.html', scheduled_for=session['scheduled_for'], **data, - ) + return render_template('views/check/preview.html', scheduled_for=session['scheduled_for'], **data) @main.route("/services//start-job/", methods=["POST"]) diff --git a/app/templates/views/check/preview.html b/app/templates/views/check/preview.html index caab43cad..8dd40e612 100644 --- a/app/templates/views/check/preview.html +++ b/app/templates/views/check/preview.html @@ -63,7 +63,7 @@ {% endcall %} {% endif %} -

This message will be delivered to 400 phone numbers and will use a total of 800 message parts, leaving Washington DSHS with 249,200 message parts remaining.

+

Placeholder: This message will be delivered to 400 phone numbers and will use a total of 800 message parts, leaving Washington DSHS with 249,200 message parts remaining.

Does everything look good?

{% set button_text %} Send diff --git a/app/templates/views/notifications/preview.html b/app/templates/views/notifications/preview.html index dd009fdcb..468e91f3b 100644 --- a/app/templates/views/notifications/preview.html +++ b/app/templates/views/notifications/preview.html @@ -53,7 +53,7 @@ help='3' if help else 0 )}}" class='page-footer'> -

This message will be delivered to 400 phone numbers and will use a total of 800 message parts, leaving Washington DSHS with 249,200 message parts remaining.

+

Placeholder: This message will be delivered to 400 phone numbers and will use a total of 800 message parts, leaving Washington DSHS with 249,200 message parts remaining.

Does everything look good?

{% if not error %} {% set button_text %} From b019dc3fe9cfd4ca944a491b4a94a8956941fb3c Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Thu, 8 Feb 2024 18:43:17 -0800 Subject: [PATCH 07/27] updated pytest --- app/assets/sass/uswds/_legacy-styles.scss | 2 +- app/main/views/send.py | 43 ++++++--- app/templates/views/check/ok.html | 6 +- app/templates/views/check/preview.html | 6 +- app/templates/views/notifications/check.html | 5 +- tests/app/main/views/test_conversation.py | 2 +- tests/app/main/views/test_send.py | 97 ++++++++++++-------- tests/app/main/views/test_tour.py | 3 +- tests/app/test_navigation.py | 2 + 9 files changed, 102 insertions(+), 64 deletions(-) diff --git a/app/assets/sass/uswds/_legacy-styles.scss b/app/assets/sass/uswds/_legacy-styles.scss index a4a6e3d2c..242bb0f74 100644 --- a/app/assets/sass/uswds/_legacy-styles.scss +++ b/app/assets/sass/uswds/_legacy-styles.scss @@ -48,7 +48,7 @@ } } -.sms-message-sender { +.sms-message-sender, .sms-message-file-name, .sms-message-scheduler { margin: units(1) 0 0; } diff --git a/app/main/views/send.py b/app/main/views/send.py index d81eca83d..90834d965 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -535,7 +535,10 @@ def _check_messages(service_id, template_id, upload_id, preview_row): "main.send_messages", service_id=service_id, template_id=template.id ) back_link_from_preview = url_for( - "main.check_messages", service_id=service_id, template_id=template.id, upload_id=upload_id + "main.check_messages", + service_id=service_id, + template_id=template.id, + upload_id=upload_id, ) choose_time_form = ChooseTimeForm() @@ -570,7 +573,7 @@ def _check_messages(service_id, template_id, upload_id, preview_row): sent_previously=job_api_client.has_sent_previously( service_id, template.id, db_template["version"], original_file_name ), - template_id=template_id + template_id=template_id, ) @@ -614,17 +617,20 @@ def check_messages(service_id, template_id, upload_id, row_index=2): metadata_kwargs["sender_id"] = session["sender_id"] set_metadata_on_csv_upload(service_id, upload_id, **metadata_kwargs) - session['scheduled_for'] = request.form.get("scheduled_for", "") return render_template("views/check/ok.html", **data) @main.route( "/services///check//preview", - methods=["POST"], + methods=["GET"], +) +@main.route( + "/services///check//preview/row-", + methods=["GET"], ) @user_has_permissions("send_messages", restrict_admin_usage=True) def preview_job(service_id, template_id, upload_id, row_index=2): - session['scheduled_for'] = request.form.get('scheduled_for', 'Not specified') + session["scheduled_for"] = request.args.get("scheduled_for", "") data = _check_messages(service_id, template_id, upload_id, row_index) data["allowed_file_extensions"] = Spreadsheet.ALLOWED_FILE_EXTENSIONS if ( @@ -643,13 +649,15 @@ def preview_job(service_id, template_id, upload_id, row_index=2): if data["errors"]: return render_template("views/check/column-errors.html", **data) - return render_template('views/check/preview.html', scheduled_for=session['scheduled_for'], **data) + return render_template( + "views/check/preview.html", scheduled_for=session["scheduled_for"], **data + ) @main.route("/services//start-job/", methods=["POST"]) @user_has_permissions("send_messages", restrict_admin_usage=True) def start_job(service_id, upload_id): - scheduled_for = session.pop('scheduled_for', None) + scheduled_for = session.pop("scheduled_for", None) job_api_client.create_job( upload_id, service_id, @@ -712,7 +720,13 @@ def get_send_test_page_title(template_type, entering_recipient, name=None): return "Personalize this message" -def get_back_link(service_id, template, step_index, placeholders=None, preview=False,): +def get_back_link( + service_id, + template, + step_index, + placeholders=None, + preview=False, +): if preview: return url_for( "main.check_notification", @@ -824,7 +838,9 @@ def _check_notification(service_id, template_id, exception=None): back_link = get_back_link(service_id, template, len(placeholders), placeholders) - back_link_from_preview = get_back_link(service_id, template, len(placeholders), placeholders, preview=True) + back_link_from_preview = get_back_link( + service_id, template, len(placeholders), placeholders, preview=True + ) choose_time_form = ChooseTimeForm() @@ -873,7 +889,7 @@ def get_template_error_dict(exception): @main.route( "/services//template//notification/check/preview", - methods=["POST"], + methods=["GET"], ) @user_has_permissions("send_messages", restrict_admin_usage=True) def preview_notification(service_id, template_id): @@ -887,11 +903,12 @@ def preview_notification(service_id, template_id): ) ) - session['scheduled_for'] = request.form.get('scheduled_for', 'Not specified') + session["scheduled_for"] = request.args.get("scheduled_for", "") return render_template( "views/notifications/preview.html", - **_check_notification(service_id, template_id), data=session['scheduled_for'] + **_check_notification(service_id, template_id), + scheduled_for=session["scheduled_for"], ) @@ -901,7 +918,7 @@ def preview_notification(service_id, template_id): ) @user_has_permissions("send_messages", restrict_admin_usage=True) def send_notification(service_id, template_id): - scheduled_for = session.pop('scheduled_for', None) + scheduled_for = session.pop("scheduled_for", "") recipient = get_recipient() if not recipient: return redirect( diff --git a/app/templates/views/check/ok.html b/app/templates/views/check/ok.html index f70b6232e..95fd1abea 100644 --- a/app/templates/views/check/ok.html +++ b/app/templates/views/check/ok.html @@ -1,6 +1,5 @@ {% extends "withnav_template.html" %} {% from "components/banner.html" import banner_wrapper %} -{% from "components/table.html" import list_table, field, text_field, index_field, hidden_field_heading %} {% from "components/page-header.html" import page_header %} {% from "components/components/button/macro.njk" import usaButton %} {% from "components/components/skip-link/macro.njk" import usaSkipLink %} @@ -9,7 +8,7 @@ {% set file_contents_header_id = 'file-preview' %} {% block service_page_title %} - {{ "Preview of {}".format(template.name) }} + {{ "Select delivery time" }} {% endblock %} @@ -23,8 +22,7 @@ {{ template|string }}
-