Merge pull request #952 from alphagov/ajax-activity-page

AJAX the activity page
This commit is contained in:
Chris Hill-Scott
2016-09-27 16:08:58 +01:00
committed by GitHub
5 changed files with 122 additions and 85 deletions

View File

@@ -2,6 +2,7 @@
import ago import ago
import time import time
import dateutil import dateutil
import json
from orderedset import OrderedSet from orderedset import OrderedSet
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from itertools import chain from itertools import chain
@@ -165,10 +166,28 @@ def view_job_updates(service_id, job_id):
@main.route('/services/<service_id>/notifications/<message_type>') @main.route('/services/<service_id>/notifications/<message_type>')
@main.route('/services/<service_id>/notifications/<message_type>.csv', endpoint="view_notifications_csv")
@login_required @login_required
@user_has_permissions('view_activity', admin_override=True) @user_has_permissions('view_activity', admin_override=True)
def view_notifications(service_id, message_type): def view_notifications(service_id, message_type):
return render_template(
'views/notifications.html',
partials=get_notifications(service_id, message_type),
message_type=message_type,
status=request.args.get('status')
)
@main.route('/services/<service_id>/notifications/<message_type>.json')
@user_has_permissions('view_activity', admin_override=True)
def get_notifications_as_json(service_id, message_type):
return jsonify(get_notifications(
service_id, message_type, status_override=request.args.get('status')
))
@main.route('/services/<service_id>/notifications/<message_type>.csv', endpoint="view_notifications_csv")
@user_has_permissions('view_activity', admin_override=True)
def get_notifications(service_id, message_type, status_override=None):
# TODO get the api to return count of pages as well. # TODO get the api to return count of pages as well.
page = get_page_from_request() page = get_page_from_request()
if page is None: if page is None:
@@ -220,26 +239,32 @@ def view_notifications(service_id, message_type):
'Content-Type': 'text/csv; charset=utf-8', 'Content-Type': 'text/csv; charset=utf-8',
'Content-Disposition': 'inline; filename="notifications.csv"' 'Content-Disposition': 'inline; filename="notifications.csv"'
} }
return render_template( return {
'views/notifications.html', 'counts': render_template(
notifications=notifications['notifications'], 'views/activity/counts.html',
page=page, status=request.args.get('status'),
prev_page=prev_page, status_filters=get_status_filters(
next_page=next_page, current_service,
status=request.args.get('status'), message_type,
message_type=message_type, service_api_client.get_detailed_service(service_id)['data']['statistics']
download_link=url_for( )
'.view_notifications_csv',
service_id=current_service['id'],
message_type=message_type,
status=request.args.get('status')
), ),
status_filters=get_status_filters( 'notifications': render_template(
current_service, 'views/activity/notifications.html',
message_type, notifications=notifications['notifications'],
service_api_client.get_detailed_service(service_id)['data']['statistics'] page=page,
) prev_page=prev_page,
) next_page=next_page,
status=request.args.get('status'),
message_type=message_type,
download_link=url_for(
'.view_notifications_csv',
service_id=current_service['id'],
message_type=message_type,
status=request.args.get('status')
)
),
}
def get_status_filters(service, message_type, statistics): def get_status_filters(service, message_type, statistics):

View File

@@ -0,0 +1,9 @@
{% from "components/pill.html" import pill %}
<div class='bottom-gutter ajax-block-container'>
{{ pill(
'Status',
status_filters,
status
) }}
</div>

View File

@@ -0,0 +1,47 @@
{% from "components/page-footer.html" import page_footer %}
{% from "components/previous-next-navigation.html" import previous_next_navigation %}
{% from "components/table.html" import list_table, field, text_field, link_field, right_aligned_field_heading, hidden_field_heading, row_heading, notification_status_field %}
<div class="ajax-block-container">
{% if notifications %}
<p class="bottom-gutter">
<a href="{{ download_link }}" download="download" class="heading-small">Download this report</a>
&emsp;
Data available for 7 days
</p>
<div class='dashboard-table'>
{% endif %}
{% call(item, row_number) list_table(
notifications,
caption="Recent activity",
caption_visible=False,
empty_message='No messages found',
field_headings=['Recipient', 'Status'],
field_headings_visible=False
) %}
{% call row_heading() %}
<p>
{{ item.to }}
</p>
<p class="hint">
{% if item.job %}
From <a href="{{ url_for(".view_job", service_id=current_service.id, job_id=item.job.id) }}">{{ item.job.original_file_name }}</a>
{% else %}
<a href="{{ url_for('.view_template_version', service_id=current_service.id, template_id=item.template.id, version=item.template_version) }}">{{ item.template.name }}</a>
from an API call
{% endif %}
</p>
{% endcall %}
{{ notification_status_field(item) }}
{% endcall %}
{% if notifications %}
</div>
{% endif %}
{{ previous_next_navigation(prev_page, next_page) }}
</div>

View File

@@ -1,8 +1,5 @@
{% extends "withnav_template.html" %} {% extends "withnav_template.html" %}
{% from "components/table.html" import list_table, field, text_field, link_field, right_aligned_field_heading, hidden_field_heading, row_heading, notification_status_field %} {% from "components/ajax-block.html" import ajax_block %}
{% from "components/previous-next-navigation.html" import previous_next_navigation %}
{% from "components/page-footer.html" import page_footer %}
{% from "components/pill.html" import pill %}
{% from "components/message-count-label.html" import message_count_label, recipient_count_label %} {% from "components/message-count-label.html" import message_count_label, recipient_count_label %}
{% block page_title %} {% block page_title %}
@@ -12,69 +9,19 @@
{% block maincolumn_content %} {% block maincolumn_content %}
<h1 class="heading-large"> <h1 class="heading-large">
{{ message_count_label(99, message_type, suffix='') | capitalize }}
<span class="visually-hidden">
{%- if status != 'delivered,failed' -%}
{%- for label, option, _, _ in status_filters -%}
{%- if status == option -%}{{label}} {% endif -%}
{%- endfor -%}
{%- endif -%}
</span>
{{- message_count_label(99, message_type, suffix='') | capitalize }}
</h1> </h1>
<div class='bottom-gutter'> {{ ajax_block(
{{ pill( partials,
'Status', url_for('.get_notifications_as_json', service_id=current_service.id, message_type=message_type, status=status),
status_filters, 'counts'
status ) }}
) }}
</div>
{% if notifications %} {{ ajax_block(
<p class="bottom-gutter"> partials,
<a href="{{ download_link }}" download="download" class="heading-small">Download this report</a> url_for('.get_notifications_as_json', service_id=current_service.id, message_type=message_type, status=status),
&emsp; 'notifications'
Data available for 7 days ) }}
</p>
{% endif %}
{% if notifications %}
<div class='dashboard-table'>
{% endif %}
{% call(item, row_number) list_table(
notifications,
caption="Recent activity",
caption_visible=False,
empty_message='No messages found',
field_headings=['Recipient', 'Status'],
field_headings_visible=False
) %}
{% call row_heading() %}
<p>
{{ item.to }}
</p>
<p class="hint">
{% if item.job %}
From <a href="{{ url_for(".view_job", service_id=current_service.id, job_id=item.job.id) }}">{{ item.job.original_file_name }}</a>
{% else %}
<a href="{{ url_for('.view_template_version', service_id=current_service.id, template_id=item.template.id, version=item.template_version) }}">{{ item.template.name }}</a>
from an API call
{% endif %}
</p>
{% endcall %}
{{ notification_status_field(item) }}
{% endcall %}
{% if notifications %}
</div>
{% endif %}
{{ previous_next_navigation(prev_page, next_page) }}
{% endblock %} {% endblock %}

View File

@@ -338,6 +338,15 @@ def test_can_show_notifications(
assert csv_response.get_data(as_text=True) == csv_content assert csv_response.get_data(as_text=True) == csv_content
assert 'text/csv' in csv_response.headers['Content-Type'] assert 'text/csv' in csv_response.headers['Content-Type']
json_response = client.get(url_for(
'main.get_notifications_as_json',
service_id=service_one['id'],
message_type=message_type,
status=status_argument
))
json_content = json.loads(json_response.get_data(as_text=True))
assert json_content.keys() == {'counts', 'notifications'}
def test_should_show_notifications_for_a_service_with_next_previous( def test_should_show_notifications_for_a_service_with_next_previous(
app_, app_,