mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-03-09 12:52:56 -04:00
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:
@@ -1,6 +1,7 @@
|
||||
from datetime import date
|
||||
from collections import namedtuple
|
||||
from itertools import groupby
|
||||
from functools import reduce
|
||||
|
||||
from flask import (
|
||||
render_template,
|
||||
@@ -29,25 +30,21 @@ from app.utils import user_has_permissions
|
||||
@login_required
|
||||
@user_has_permissions('view_activity', admin_override=True)
|
||||
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'):
|
||||
session.pop('invited_user', None)
|
||||
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(
|
||||
'views/dashboard/dashboard.html',
|
||||
jobs=jobs[:5],
|
||||
more_jobs_to_show=(len(jobs) > 5),
|
||||
free_text_messages_remaining='250,000',
|
||||
spent_this_month='0.00',
|
||||
statistics=add_rates_to(statistics),
|
||||
templates=templates,
|
||||
template_statistics=template_statistics)
|
||||
statistics=add_rates_to(
|
||||
statistics_api_client.get_statistics_for_service(service_id)['data']
|
||||
),
|
||||
templates=service_api_client.get_service_templates(service_id)['data'],
|
||||
template_statistics=aggregate_usage(
|
||||
template_statistics_client.get_template_statistics_for_service(service_id)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@main.route("/services/<service_id>/dashboard.json")
|
||||
@@ -60,8 +57,12 @@ def service_dashboard_updates(service_id):
|
||||
return jsonify(**{
|
||||
'today': render_template(
|
||||
'views/dashboard/today.html',
|
||||
statistics=add_rates_to(statistics),
|
||||
template_statistics=template_statistics
|
||||
statistics=add_rates_to(
|
||||
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]:
|
||||
return {}
|
||||
|
||||
today = None
|
||||
latest_stats = {}
|
||||
if delivery_statistics[0]['day'] == date.today().strftime('%Y-%m-%d'):
|
||||
today = delivery_statistics[0]
|
||||
latest_stats = delivery_statistics[0]
|
||||
sum_of_statistics = reduce(
|
||||
lambda x, y: {
|
||||
key: x.get(key, 0) + y.get(key, 0)
|
||||
for key in [
|
||||
'emails_delivered',
|
||||
'emails_requested',
|
||||
'emails_failed',
|
||||
'sms_requested',
|
||||
'sms_delivered',
|
||||
'sms_failed'
|
||||
]
|
||||
},
|
||||
delivery_statistics
|
||||
)
|
||||
|
||||
latest_stats.update({
|
||||
'emails_failure_rate': (
|
||||
"{0:.1f}".format((float(today['emails_failed']) / today['emails_requested'] * 100))
|
||||
if today and today['emails_requested'] else 0
|
||||
return dict(
|
||||
emails_failure_rate=(
|
||||
"{0:.1f}".format((float(sum_of_statistics['emails_failed']) / sum_of_statistics['emails_requested'] * 100))
|
||||
if sum_of_statistics.get('emails_requested') else 0
|
||||
),
|
||||
'sms_failure_rate': (
|
||||
"{0:.1f}".format((float(today['sms_failed']) / today['sms_requested'] * 100))
|
||||
if today and today['sms_requested'] else 0
|
||||
)
|
||||
})
|
||||
|
||||
return latest_stats
|
||||
sms_failure_rate=(
|
||||
"{0:.1f}".format((float(sum_of_statistics['sms_failed']) / sum_of_statistics['sms_requested'] * 100))
|
||||
if sum_of_statistics.get('sms_requested') else 0
|
||||
),
|
||||
**sum_of_statistics
|
||||
)
|
||||
|
||||
|
||||
def aggregate_usage(template_statistics):
|
||||
|
||||
@@ -6,12 +6,18 @@
|
||||
{% 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">
|
||||
{{ big_number(number, label) }}
|
||||
<div class="big-number-status{% if danger_zone %}-failing{% endif %}">
|
||||
{% 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 %}
|
||||
No failures
|
||||
{% endif %}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
{% from "components/table.html" import list_table, field, hidden_field_heading, right_aligned_field_heading %}
|
||||
{% call(item, row_number) list_table(
|
||||
template_statistics,
|
||||
caption="In the last 7 days",
|
||||
caption="By template",
|
||||
caption_visible=False,
|
||||
empty_message='You haven’t 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() %}
|
||||
<a href="{{ url_for('.view_template', service_id=current_service.id, template_id=item.template.id) }}">
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
{% from "components/big-number.html" import big_number_with_status %}
|
||||
|
||||
<h2 class="heading-medium">
|
||||
Sent today
|
||||
In the last 7 days
|
||||
</h2>
|
||||
<div class="grid-row">
|
||||
<div class="grid-row bottom-gutter">
|
||||
<div class="column-half">
|
||||
{{ big_number_with_status(
|
||||
statistics.get('emails_requested', 0),
|
||||
'email' if statistics.get('emails_requested') == 1 else 'emails',
|
||||
statistics.get('emails_delivered', 0),
|
||||
'email' if statistics.get('emails_delivered') == 1 else 'emails',
|
||||
statistics.get('emails_failed'),
|
||||
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 class="column-half">
|
||||
@@ -19,10 +20,10 @@
|
||||
'text message' if statistics.get('sms_requested') == 1 else 'text messages',
|
||||
statistics.get('sms_failed'),
|
||||
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>
|
||||
|
||||
{% include 'views/dashboard/template-statistics.html' %}
|
||||
|
||||
|
||||
@@ -83,9 +83,9 @@ def test_should_show_recent_templates_on_dashboard(app_,
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
headers = [header.text.strip() for header in page.find_all('h2')]
|
||||
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')]
|
||||
for th in ['Template', 'Type', 'Messages sent']:
|
||||
for th in ['Template', 'Type', 'Messages processed']:
|
||||
assert th in template_usage_headers
|
||||
table_rows = page.tbody.find_all('tr')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user