mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-11 09:28:27 -04:00
Make list of templates filterable by type
When users are trying to find a template there’s a fair chance that they know whether or not it’s an email/text message/(letter) that they’re looking for. Making them scroll past a whole bunch of templates of a different type means it will take them longer to find the template they are looking for. We already have search on the templates page, but this is only good for where they can remember the name of the template. This will be sometimes but not always. This commit adds some navigation to filter down the list of templates to only show one type at a time. By default it will show all templates. It adapts the pattern we use for filtering notifications by sending/failed/delivered, but without the counts of how many things are in each bucket (I don’t think there’s any value in knowing you have X text message templates; on this page you only really care about the one template you’re looking for). _Note: required re-arranging the functions in `templates.py`. The route for `/template/:uuid` needs to come before the route for `template/:string` otherwise Flask tries to interpret a template’s ID as its type.
This commit is contained in:
@@ -43,26 +43,7 @@ page_headings = {
|
||||
}
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/templates", methods=['GET'])
|
||||
@login_required
|
||||
@user_has_permissions(
|
||||
'view_activity',
|
||||
'send_texts',
|
||||
'send_emails',
|
||||
'manage_templates',
|
||||
'manage_api_keys',
|
||||
admin_override=True,
|
||||
any_=True,
|
||||
)
|
||||
def choose_template(service_id):
|
||||
return render_template(
|
||||
'views/templates/choose.html',
|
||||
templates=service_api_client.get_service_templates(service_id)['data'],
|
||||
search_form=SearchTemplatesForm(),
|
||||
)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/templates/<template_id>")
|
||||
@main.route("/services/<service_id>/templates/<uuid:template_id>")
|
||||
@login_required
|
||||
@user_has_permissions(
|
||||
'view_activity',
|
||||
@@ -73,7 +54,7 @@ def choose_template(service_id):
|
||||
admin_override=True, any_=True
|
||||
)
|
||||
def view_template(service_id, template_id):
|
||||
template = service_api_client.get_service_template(service_id, template_id)['data']
|
||||
template = service_api_client.get_service_template(service_id, str(template_id))['data']
|
||||
return render_template(
|
||||
'views/templates/template.html',
|
||||
template=get_template(
|
||||
@@ -92,6 +73,43 @@ def view_template(service_id, template_id):
|
||||
)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/templates")
|
||||
@main.route("/services/<service_id>/templates/<template_type>")
|
||||
@login_required
|
||||
@user_has_permissions(
|
||||
'view_activity',
|
||||
'send_texts',
|
||||
'send_emails',
|
||||
'manage_templates',
|
||||
'manage_api_keys',
|
||||
admin_override=True,
|
||||
any_=True,
|
||||
)
|
||||
def choose_template(service_id, template_type='all'):
|
||||
templates = service_api_client.get_service_templates(service_id)['data']
|
||||
|
||||
template_nav_items = [
|
||||
(label, key, url_for('.choose_template', service_id=current_service['id'], template_type=key), '')
|
||||
for label, key in filter(None, [
|
||||
('All', 'all'),
|
||||
('Text message', 'sms'),
|
||||
('Email', 'email'),
|
||||
('Letter', 'letter') if current_service['can_send_letters'] else None,
|
||||
])
|
||||
]
|
||||
|
||||
return render_template(
|
||||
'views/templates/choose.html',
|
||||
templates=[
|
||||
template for template in templates
|
||||
if template_type in ['all', template['template_type']]
|
||||
],
|
||||
template_nav_items=template_nav_items,
|
||||
template_type=template_type,
|
||||
search_form=SearchTemplatesForm(),
|
||||
)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/templates/<template_id>.<filetype>")
|
||||
@login_required
|
||||
@user_has_permissions('view_activity', admin_override=True)
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
{% macro pill(
|
||||
items=[],
|
||||
current_value=None,
|
||||
big_number_args={'smaller': True}
|
||||
big_number_args={'smaller': True},
|
||||
show_count=True
|
||||
) %}
|
||||
<ul role='tablist' class='pill'>
|
||||
{% for label, option, link, count in items %}
|
||||
@@ -14,7 +15,9 @@
|
||||
<li aria-selected='false' role='tab'>
|
||||
<a href="{{ link }}">
|
||||
{% endif %}
|
||||
{% if show_count %}
|
||||
{{ big_number(count, **big_number_args) }}
|
||||
{% endif %}
|
||||
<div class="pill-label">{{ label }}</div>
|
||||
{% if current_value == option %}
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{% from "components/pill.html" import pill %}
|
||||
{% from "components/message-count-label.html" import message_count_label %}
|
||||
{% from "components/textbox.html" import textbox %}
|
||||
|
||||
@@ -36,7 +37,7 @@
|
||||
|
||||
{% else %}
|
||||
|
||||
<div class="grid-row bottom-gutter-1-2">
|
||||
<div class="grid-row bottom-gutter-2-3">
|
||||
<div class="column-two-thirds">
|
||||
<h1 class="heading-large">Templates</h1>
|
||||
</div>
|
||||
@@ -47,6 +48,10 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="bottom-gutter-2-3">
|
||||
{{ pill(template_nav_items, current_value=template_type, show_count=False) }}
|
||||
</div>
|
||||
|
||||
{% if templates|length > 7 %}
|
||||
<div data-module="autofocus">
|
||||
<div class="live-search" data-module="live-search" data-targets="#template-list .column-whole">
|
||||
|
||||
@@ -7,13 +7,63 @@ from flask import url_for
|
||||
from freezegun import freeze_time
|
||||
from notifications_python_client.errors import HTTPError
|
||||
from tests.conftest import service_one as create_sample_service
|
||||
from tests.conftest import mock_get_service_email_template, mock_get_service_letter_template
|
||||
from tests.conftest import mock_get_service_email_template, mock_get_service_letter_template, SERVICE_ONE_ID
|
||||
from tests import validate_route_permission, template_json, single_notification_json
|
||||
from tests.app.test_utils import normalize_spaces
|
||||
|
||||
from app.main.views.templates import get_last_use_message, get_human_readable_delta
|
||||
|
||||
|
||||
@pytest.mark.parametrize('extra_args, expected_nav_links, expected_templates', [
|
||||
(
|
||||
{},
|
||||
['Text message', 'Email'],
|
||||
['sms_template_one', 'sms_template_two', 'email_template_one', 'email_template_two']
|
||||
),
|
||||
(
|
||||
{'template_type': 'sms'},
|
||||
['All', 'Email'],
|
||||
['sms_template_one', 'sms_template_two'],
|
||||
),
|
||||
(
|
||||
{'template_type': 'email'},
|
||||
['All', 'Text message'],
|
||||
['email_template_one', 'email_template_two'],
|
||||
),
|
||||
])
|
||||
def test_should_show_page_for_choosing_a_template(
|
||||
client_request,
|
||||
mock_get_service_templates,
|
||||
extra_args,
|
||||
expected_nav_links,
|
||||
expected_templates,
|
||||
):
|
||||
|
||||
page = client_request.get(
|
||||
'main.choose_template',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
**extra_args
|
||||
)
|
||||
|
||||
assert normalize_spaces(page.select('h1')[0].text) == 'Templates'
|
||||
|
||||
links_in_page = page.select('.pill a')
|
||||
|
||||
assert len(links_in_page) == len(expected_nav_links)
|
||||
|
||||
for index, expected_link in enumerate(expected_nav_links):
|
||||
assert links_in_page[index].text.strip() == expected_link
|
||||
|
||||
template_links = page.select('.message-name a')
|
||||
|
||||
assert len(template_links) == len(expected_templates)
|
||||
|
||||
for index, expected_template in enumerate(expected_templates):
|
||||
assert template_links[index].text.strip() == expected_template
|
||||
|
||||
mock_get_service_templates.assert_called_with(SERVICE_ONE_ID)
|
||||
|
||||
|
||||
def test_should_show_page_for_one_template(
|
||||
logged_in_client,
|
||||
mock_get_service_template,
|
||||
|
||||
Reference in New Issue
Block a user