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 @@