diff --git a/hc/accounts/admin.py b/hc/accounts/admin.py index 17f5a58d..deabc73f 100644 --- a/hc/accounts/admin.py +++ b/hc/accounts/admin.py @@ -21,7 +21,7 @@ class Fieldset: class ProfileFieldset(Fieldset): name = "User Profile" fields = ("email", "api_key", "current_team", "reports_allowed", - "next_report_date", "token") + "next_report_date", "token", "sort") class TeamFieldset(Fieldset): diff --git a/hc/accounts/migrations/0011_profile_sort.py b/hc/accounts/migrations/0011_profile_sort.py new file mode 100644 index 00000000..31c6133f --- /dev/null +++ b/hc/accounts/migrations/0011_profile_sort.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2017-09-12 14:24 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0010_profile_team_limit'), + ] + + operations = [ + migrations.AddField( + model_name='profile', + name='sort', + field=models.CharField(default='created', max_length=20), + ), + ] diff --git a/hc/accounts/models.py b/hc/accounts/models.py index b74fbe76..8d8e2001 100644 --- a/hc/accounts/models.py +++ b/hc/accounts/models.py @@ -51,6 +51,7 @@ class Profile(models.Model): sms_limit = models.IntegerField(default=0) sms_sent = models.IntegerField(default=0) team_limit = models.IntegerField(default=2) + sort = models.CharField(max_length=20, default="created") objects = ProfileManager() diff --git a/hc/front/tests/test_my_checks.py b/hc/front/tests/test_my_checks.py index 2228adbf..a5c1a780 100644 --- a/hc/front/tests/test_my_checks.py +++ b/hc/front/tests/test_my_checks.py @@ -66,3 +66,17 @@ class MyChecksTestCase(BaseTestCase): self.client.login(username="alice@example.org", password="password") r = self.client.get("/checks/") self.assertContains(r, "Check limit reached", status_code=200) + + def test_it_saves_sort_field(self): + self.client.login(username="alice@example.org", password="password") + self.client.get("/checks/?sort=name") + + self.profile.refresh_from_db() + self.assertEqual(self.profile.sort, "name") + + def test_it_ignores_bad_sort_value(self): + self.client.login(username="alice@example.org", password="password") + self.client.get("/checks/?sort=invalid") + + self.profile.refresh_from_db() + self.assertEqual(self.profile.sort, "created") diff --git a/hc/front/views.py b/hc/front/views.py index 3e3a231b..7ad2bcce 100644 --- a/hc/front/views.py +++ b/hc/front/views.py @@ -1,4 +1,3 @@ -from collections import Counter from datetime import datetime, timedelta as td import json @@ -32,17 +31,24 @@ from pytz.exceptions import UnknownTimeZoneError import requests +VALID_SORT_VALUES = ("name", "-name", "last_ping", "-last_ping", "created") + + @login_required def my_checks(request): - q = Check.objects.filter(user=request.team.user).order_by("created") + if request.GET.get("sort") in VALID_SORT_VALUES: + request.profile.sort = request.GET["sort"] + request.profile.save() + + q = Check.objects.filter(user=request.team.user) + q = q.order_by(request.profile.sort) checks = list(q) - counter = Counter() - down_tags, grace_tags = set(), set() + tags, down_tags, grace_tags = set(), set(), set() for check in checks: status = check.get_status() for tag in check.tags_list(): - counter[tag] += 1 + tags.add(tag) if status == "down": down_tags.add(tag) @@ -55,12 +61,13 @@ def my_checks(request): "page": "checks", "checks": checks, "now": timezone.now(), - "tags": counter.most_common(), + "tags": sorted(tags, key=lambda s: s.lower()), "down_tags": down_tags, "grace_tags": grace_tags, "ping_endpoint": settings.PING_ENDPOINT, "timezones": all_timezones, - "can_add_more": can_add_more + "can_add_more": can_add_more, + "sort": request.profile.sort } return render(request, "front/my_checks.html", ctx) diff --git a/static/css/icomoon.css b/static/css/icomoon.css index 287b9c92..6c42598c 100644 --- a/static/css/icomoon.css +++ b/static/css/icomoon.css @@ -1,10 +1,10 @@ @font-face { font-family: 'icomoon'; - src: url('../fonts/icomoon.eot?cxijqz'); - src: url('../fonts/icomoon.eot?cxijqz#iefix') format('embedded-opentype'), - url('../fonts/icomoon.ttf?cxijqz') format('truetype'), - url('../fonts/icomoon.woff?cxijqz') format('woff'), - url('../fonts/icomoon.svg?cxijqz#icomoon') format('svg'); + src: url('../fonts/icomoon.eot?rq3u8q'); + src: url('../fonts/icomoon.eot?rq3u8q#iefix') format('embedded-opentype'), + url('../fonts/icomoon.ttf?rq3u8q') format('truetype'), + url('../fonts/icomoon.woff?rq3u8q') format('woff'), + url('../fonts/icomoon.svg?rq3u8q#icomoon') format('svg'); font-weight: normal; font-style: normal; } @@ -24,42 +24,45 @@ -moz-osx-font-smoothing: grayscale; } -.icon-clippy:before { - content: "\e900"; -} .icon-cancel:before { content: "\e5c9"; } -.icon-ok:before { - content: "\e86d"; -} -.icon-up:before { - content: "\e86c"; -} .icon-close:before { content: "\e5cd"; } -.icon-delete:before { - content: "\e872"; -} -.icon-mail:before { - content: "\e159"; -} .icon-grace:before { content: "\e000"; } .icon-missing:before { content: "\e001"; } +.icon-asc:before { + content: "\e5ce"; +} +.icon-desc:before { + content: "\e5cf"; +} .icon-dots:before { content: "\e5d3"; } .icon-down:before { - content: "\e7f8"; + content: "\e7f7"; } .icon-paused:before { - content: "\e7f7"; + content: "\e7f6"; } .icon-settings:before { content: "\e8b8"; +} +.icon-mail:before { + content: "\e900"; +} +.icon-delete:before { + content: "\e901"; +} +.icon-up:before, .icon-ok:before { + content: "\e902"; +} +.icon-clippy:before { + content: "\e903"; } \ No newline at end of file diff --git a/static/css/my_checks_desktop.css b/static/css/my_checks_desktop.css index e63ab941..fe4a509b 100644 --- a/static/css/my_checks_desktop.css +++ b/static/css/my_checks_desktop.css @@ -24,6 +24,18 @@ table.table tr > th.th-name { border-top: 0; } +#checks-table th { + border-top: 0; +} + +#checks-table a.default { + color: #333; +} + +#checks-table tr:hover a.default { + color: #0091EA; +} + #checks-table td { vertical-align: middle; border-top: 1px solid #f1f1f1; diff --git a/static/fonts/icomoon.eot b/static/fonts/icomoon.eot index 87082976..1b4b9a32 100644 Binary files a/static/fonts/icomoon.eot and b/static/fonts/icomoon.eot differ diff --git a/static/fonts/icomoon.svg b/static/fonts/icomoon.svg index 7b548958..dd63d0a7 100644 --- a/static/fonts/icomoon.svg +++ b/static/fonts/icomoon.svg @@ -9,15 +9,16 @@ - + + - - - - - + + - + + + + \ No newline at end of file diff --git a/static/fonts/icomoon.ttf b/static/fonts/icomoon.ttf index cea03cff..af330583 100644 Binary files a/static/fonts/icomoon.ttf and b/static/fonts/icomoon.ttf differ diff --git a/static/fonts/icomoon.woff b/static/fonts/icomoon.woff index 8c57375e..da5cc176 100644 Binary files a/static/fonts/icomoon.woff and b/static/fonts/icomoon.woff differ diff --git a/templates/front/my_checks.html b/templates/front/my_checks.html index fe698e3a..fb388ec5 100644 --- a/templates/front/my_checks.html +++ b/templates/front/my_checks.html @@ -17,7 +17,7 @@ {% if tags %}
- {% for tag, count in tags %} + {% for tag in tags %} {% if tag in down_tags %} {% elif tag in grace_tags %} diff --git a/templates/front/my_checks_desktop.html b/templates/front/my_checks_desktop.html index d81e410d..877e3efd 100644 --- a/templates/front/my_checks_desktop.html +++ b/templates/front/my_checks_desktop.html @@ -2,13 +2,29 @@ - + - + {% for check in checks %}