Show all statistics fetched on the dashboard

We want to align all our stats to be for the last 7 days.

This means summing up the stats response from the API to make the Big
Number. Previously the big number was counting sent notifications as
successful. This commit changes it to only look at delivered
notifications.

Right now, the API doesn’t have a way of filtering to only show the last
7 days. So for the moment the dashboard will show statistics for all
time.

The upshot of this is that we can link from the dashboard to the
activity page when there are failures.
This commit is contained in:
Chris Hill-Scott
2016-04-19 12:57:55 +01:00
parent ddec619913
commit 5bf0d8fe70
5 changed files with 60 additions and 43 deletions

View File

@@ -1,6 +1,7 @@
from datetime import date from datetime import date
from collections import namedtuple from collections import namedtuple
from itertools import groupby from itertools import groupby
from functools import reduce
from flask import ( from flask import (
render_template, render_template,
@@ -29,25 +30,21 @@ from app.utils import user_has_permissions
@login_required @login_required
@user_has_permissions('view_activity', admin_override=True) @user_has_permissions('view_activity', admin_override=True)
def service_dashboard(service_id): def service_dashboard(service_id):
templates = service_api_client.get_service_templates(service_id)['data']
jobs = job_api_client.get_job(service_id)['data']
if session.get('invited_user'): if session.get('invited_user'):
session.pop('invited_user', None) session.pop('invited_user', None)
return redirect(url_for("main.tour", service_id=service_id, page=1)) return redirect(url_for("main.tour", service_id=service_id, page=1))
statistics = statistics_api_client.get_statistics_for_service(service_id)['data']
template_statistics = aggregate_usage(template_statistics_client.get_template_statistics_for_service(service_id))
return render_template( return render_template(
'views/dashboard/dashboard.html', 'views/dashboard/dashboard.html',
jobs=jobs[:5], statistics=add_rates_to(
more_jobs_to_show=(len(jobs) > 5), statistics_api_client.get_statistics_for_service(service_id)['data']
free_text_messages_remaining='250,000', ),
spent_this_month='0.00', templates=service_api_client.get_service_templates(service_id)['data'],
statistics=add_rates_to(statistics), template_statistics=aggregate_usage(
templates=templates, template_statistics_client.get_template_statistics_for_service(service_id)
template_statistics=template_statistics) )
)
@main.route("/services/<service_id>/dashboard.json") @main.route("/services/<service_id>/dashboard.json")
@@ -60,8 +57,12 @@ def service_dashboard_updates(service_id):
return jsonify(**{ return jsonify(**{
'today': render_template( 'today': render_template(
'views/dashboard/today.html', 'views/dashboard/today.html',
statistics=add_rates_to(statistics), statistics=add_rates_to(
template_statistics=template_statistics statistics_api_client.get_statistics_for_service(service_id)['data']
),
template_statistics=aggregate_usage(
template_statistics_client.get_template_statistics_for_service(service_id)
)
) )
}) })
@@ -71,24 +72,32 @@ def add_rates_to(delivery_statistics):
if not delivery_statistics or not delivery_statistics[0]: if not delivery_statistics or not delivery_statistics[0]:
return {} return {}
today = None sum_of_statistics = reduce(
latest_stats = {} lambda x, y: {
if delivery_statistics[0]['day'] == date.today().strftime('%Y-%m-%d'): key: x.get(key, 0) + y.get(key, 0)
today = delivery_statistics[0] for key in [
latest_stats = delivery_statistics[0] 'emails_delivered',
'emails_requested',
'emails_failed',
'sms_requested',
'sms_delivered',
'sms_failed'
]
},
delivery_statistics
)
latest_stats.update({ return dict(
'emails_failure_rate': ( emails_failure_rate=(
"{0:.1f}".format((float(today['emails_failed']) / today['emails_requested'] * 100)) "{0:.1f}".format((float(sum_of_statistics['emails_failed']) / sum_of_statistics['emails_requested'] * 100))
if today and today['emails_requested'] else 0 if sum_of_statistics.get('emails_requested') else 0
), ),
'sms_failure_rate': ( sms_failure_rate=(
"{0:.1f}".format((float(today['sms_failed']) / today['sms_requested'] * 100)) "{0:.1f}".format((float(sum_of_statistics['sms_failed']) / sum_of_statistics['sms_requested'] * 100))
if today and today['sms_requested'] else 0 if sum_of_statistics.get('sms_requested') else 0
) ),
}) **sum_of_statistics
)
return latest_stats
def aggregate_usage(template_statistics): def aggregate_usage(template_statistics):

View File

@@ -6,12 +6,18 @@
{% endmacro %} {% endmacro %}
{% macro big_number_with_status(number, label, failures, failure_percentage, danger_zone=False) %} {% macro big_number_with_status(number, label, failures, failure_percentage, danger_zone=False, failure_link=None) %}
<div class="big-number-with-status"> <div class="big-number-with-status">
{{ big_number(number, label) }} {{ big_number(number, label) }}
<div class="big-number-status{% if danger_zone %}-failing{% endif %}"> <div class="big-number-status{% if danger_zone %}-failing{% endif %}">
{% if failures %} {% if failures %}
{{ failures }} failed {{ failure_percentage }}% {% if failure_link %}
<a href="{{ failure_link }}">
{{ failures }} failed {{ failure_percentage }}%
</a>
{% else %}
{{ failures }} failed {{ failure_percentage }}%
{% endif %}
{% else %} {% else %}
No failures No failures
{% endif %} {% endif %}

View File

@@ -1,9 +1,10 @@
{% from "components/table.html" import list_table, field, hidden_field_heading, right_aligned_field_heading %} {% from "components/table.html" import list_table, field, hidden_field_heading, right_aligned_field_heading %}
{% call(item, row_number) list_table( {% call(item, row_number) list_table(
template_statistics, template_statistics,
caption="In the last 7 days", caption="By template",
caption_visible=False,
empty_message='You havent set up any templates yet', empty_message='You havent set up any templates yet',
field_headings=['Template', hidden_field_heading('Type'), right_aligned_field_heading('Messages sent')] field_headings=['Template', hidden_field_heading('Type'), right_aligned_field_heading('Messages processed')]
) %} ) %}
{% call field() %} {% call field() %}
<a href="{{ url_for('.view_template', service_id=current_service.id, template_id=item.template.id) }}"> <a href="{{ url_for('.view_template', service_id=current_service.id, template_id=item.template.id) }}">

View File

@@ -1,16 +1,17 @@
{% from "components/big-number.html" import big_number_with_status %} {% from "components/big-number.html" import big_number_with_status %}
<h2 class="heading-medium"> <h2 class="heading-medium">
Sent today In the last 7 days
</h2> </h2>
<div class="grid-row"> <div class="grid-row bottom-gutter">
<div class="column-half"> <div class="column-half">
{{ big_number_with_status( {{ big_number_with_status(
statistics.get('emails_requested', 0), statistics.get('emails_delivered', 0),
'email' if statistics.get('emails_requested') == 1 else 'emails', 'email' if statistics.get('emails_delivered') == 1 else 'emails',
statistics.get('emails_failed'), statistics.get('emails_failed'),
statistics.get('emails_failure_rate', 0.0), statistics.get('emails_failure_rate', 0.0),
statistics.get('emails_failure_rate', 0)|float > 3 statistics.get('emails_failure_rate', 0)|float > 3,
failure_link=url_for(".view_notifications", service_id=current_service.id, template_type='email', status='failed')
) }} ) }}
</div> </div>
<div class="column-half"> <div class="column-half">
@@ -19,10 +20,10 @@
'text message' if statistics.get('sms_requested') == 1 else 'text messages', 'text message' if statistics.get('sms_requested') == 1 else 'text messages',
statistics.get('sms_failed'), statistics.get('sms_failed'),
statistics.get('sms_failure_rate', 0.0), statistics.get('sms_failure_rate', 0.0),
statistics.get('sms_failure_rate', 0)|float > 3 statistics.get('sms_failure_rate', 0)|float > 3,
failure_link=url_for(".view_notifications", service_id=current_service.id, template_type='sms', status='failed')
) }} ) }}
</div> </div>
</div> </div>
{% include 'views/dashboard/template-statistics.html' %} {% include 'views/dashboard/template-statistics.html' %}

View File

@@ -83,9 +83,9 @@ def test_should_show_recent_templates_on_dashboard(app_,
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
headers = [header.text.strip() for header in page.find_all('h2')] headers = [header.text.strip() for header in page.find_all('h2')]
assert 'Test Service' in headers assert 'Test Service' in headers
assert 'Sent today' in headers assert 'In the last 7 days' in headers
template_usage_headers = [th.text.strip() for th in page.thead.find_all('th')] template_usage_headers = [th.text.strip() for th in page.thead.find_all('th')]
for th in ['Template', 'Type', 'Messages sent']: for th in ['Template', 'Type', 'Messages processed']:
assert th in template_usage_headers assert th in template_usage_headers
table_rows = page.tbody.find_all('tr') table_rows = page.tbody.find_all('tr')