From b2ebaf153abccc974268a39af472d610c11e6465 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Fri, 18 Oct 2019 16:43:52 +0100 Subject: [PATCH] Chunk events by day MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scanning the page is difficult at the moment because it’s hard to tell how far apart in time events are, and thereby determine which events might be related. Grouping the events by day quickly lets users narrow their focus to a meaningful subset of the events. --- app/__init__.py | 5 ++ app/assets/stylesheets/main.scss | 1 + app/assets/stylesheets/views/history.scss | 29 ++++++++++++ app/main/views/history.py | 18 +++++++- app/templates/views/temp-history.html | 32 +++++++++---- tests/app/main/views/test_history.py | 56 +++++++++++++++++------ tests/conftest.py | 3 +- 7 files changed, 121 insertions(+), 23 deletions(-) create mode 100644 app/assets/stylesheets/views/history.scss diff --git a/app/__init__.py b/app/__init__.py index 2b98ab712..fb904e4f6 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -328,6 +328,10 @@ def format_date_short(date): return _format_datetime_short(utc_string_to_aware_gmt_datetime(date)) +def format_date_human(date): + return get_human_day(date) + + def _format_datetime_short(datetime): return datetime.strftime('%d %B').lstrip('0') @@ -681,6 +685,7 @@ def add_template_filters(application): valid_phone_number, linkable_name, format_date, + format_date_human, format_date_normal, format_date_short, format_datetime_relative, diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss index ceb233650..c58b6b607 100644 --- a/app/assets/stylesheets/main.scss +++ b/app/assets/stylesheets/main.scss @@ -75,6 +75,7 @@ $path: '/static/images/'; @import 'views/template'; @import 'views/notification'; @import 'views/send'; +@import 'views/history'; // TODO: break this up @import 'app'; diff --git a/app/assets/stylesheets/views/history.scss b/app/assets/stylesheets/views/history.scss new file mode 100644 index 000000000..b971a1726 --- /dev/null +++ b/app/assets/stylesheets/views/history.scss @@ -0,0 +1,29 @@ +$item-top-padding: $gutter-half; + +.history-list { + + @include core-19; + margin-bottom: $gutter; + + &-item { + + padding: $item-top-padding 0 $gutter-half 0; + border-top: 1px solid $border-colour; + position: relative; + + &:last-child { + border-bottom: 1px solid $border-colour; + } + + } + + &-user { + display: block; + } + + &-time { + display: block; + color: $secondary-text-colour; + } + +} diff --git a/app/main/views/history.py b/app/main/views/history.py index 217177ff5..222a44490 100644 --- a/app/main/views/history.py +++ b/app/main/views/history.py @@ -1,5 +1,8 @@ +from collections import defaultdict + from flask import render_template +from app import current_service, format_date_numeric from app.main import main from app.utils import user_has_permissions @@ -7,4 +10,17 @@ from app.utils import user_has_permissions @main.route("/services//history") @user_has_permissions('manage_service') def history(service_id): - return render_template('views/temp-history.html') + return render_template( + 'views/temp-history.html', + days=_chunk_events_by_day(current_service.history) + ) + + +def _chunk_events_by_day(events): + + days = defaultdict(list) + + for event in reversed(events): + days[format_date_numeric(event.time)].append(event) + + return sorted(days.items(), reverse=True) diff --git a/app/templates/views/temp-history.html b/app/templates/views/temp-history.html index 6ca2b7764..798047c49 100644 --- a/app/templates/views/temp-history.html +++ b/app/templates/views/temp-history.html @@ -10,12 +10,28 @@ Service and API key history {{ page_header("Service and API key history") }} - + {% for day, events in days %} +

+ {{ events[0].time|format_date_human|title }} +

+ + {% endfor %} + {% endblock %} diff --git a/tests/app/main/views/test_history.py b/tests/app/main/views/test_history.py index 17e8ba7a7..6a41898b8 100644 --- a/tests/app/main/views/test_history.py +++ b/tests/app/main/views/test_history.py @@ -7,16 +7,46 @@ def test_history( ): page = client_request.get('main.history', service_id=SERVICE_ONE_ID) - assert normalize_spaces( - page.select_one('main').text - ) == ( - 'Service and API key history ' - '11 November at 12:12pm 6ce466d0-fd6a-11e5-82f5-e0accb9d11a6' - ' Revoked the ‘Bad key’ API key ' - '11 November at 11:11am 6ce466d0-fd6a-11e5-82f5-e0accb9d11a6' - ' Created an API key called ‘Bad key’ ' - '10 October at 11:10am 6ce466d0-fd6a-11e5-82f5-e0accb9d11a6' - ' Created an API key called ‘Good key’ ' - '10 October at 11:10am 6ce466d0-fd6a-11e5-82f5-e0accb9d11a6' - ' Created this service and called it ‘Example service’' - ) + assert page.select_one('h1').text == 'Service and API key history' + + headings = page.select('main h2') + events = page.select('main ul') + + assert len(headings) == len(events) + assert [ + ( + normalize_spaces(headings[index].text), + normalize_spaces(events[index].text), + ) for index in range(len(headings)) + ] == [ + ( + '12 December', + ( + '6ce466d0-fd6a-11e5-82f5-e0accb9d11a6 12:12pm ' + 'Renamed this service from ‘Example service’ to ‘Real service’' + ), + ), + ( + '11 November', + ( + '6ce466d0-fd6a-11e5-82f5-e0accb9d11a6 12:12pm ' + 'Revoked the ‘Bad key’ API key' + ), + ), + ( + '11 November', + ( + '6ce466d0-fd6a-11e5-82f5-e0accb9d11a6 11:11am ' + 'Created an API key called ‘Bad key’' + ), + ), + ( + '10 October', + ( + '6ce466d0-fd6a-11e5-82f5-e0accb9d11a6 11:10am ' + 'Created an API key called ‘Good key’ ' + '6ce466d0-fd6a-11e5-82f5-e0accb9d11a6 11:10am ' + 'Created this service and called it ‘Example service’' + ), + ), + ] diff --git a/tests/conftest.py b/tests/conftest.py index ca097949f..b077122bc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3514,9 +3514,10 @@ def mock_get_service_history(mocker): 'created_by_id': sample_uuid(), }, { + 'name': 'Real service', 'created_at': '2010-10-10T10:10:10.000000Z', 'updated_at': '2012-12-12T12:12:12.000000Z', - 'created_by_id': uuid4(), + 'created_by_id': sample_uuid(), }, ], 'api_key_history': [