forked from GithubBackups/healthchecks
Checks can be sorted by name or last ping. Fixes #136
This commit is contained in:
parent
23b237ed96
commit
fc8d9ffe48
@ -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):
|
||||
|
20
hc/accounts/migrations/0011_profile_sort.py
Normal file
20
hc/accounts/migrations/0011_profile_sort.py
Normal file
@ -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),
|
||||
),
|
||||
]
|
@ -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()
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -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";
|
||||
}
|
@ -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;
|
||||
|
Binary file not shown.
@ -9,15 +9,16 @@
|
||||
<glyph unicode=" " horiz-adv-x="512" d="" />
|
||||
<glyph unicode="" glyph-name="grace" d="M554 384.667v256h-84v-256h84zM554 212.667v86h-84v-86h84zM512 852.667c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
|
||||
<glyph unicode="" glyph-name="missing" d="M512 84.667c188 0 342 154 342 342s-154 342-342 342-342-154-342-342 154-342 342-342zM512 852.667c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426zM470 640.667h84v-256h-84v256zM470 298.667h84v-86h-84v86z" />
|
||||
<glyph unicode="" glyph-name="mail" d="M854 596.667v86l-342-214-342 214v-86l342-212zM854 768.667c46 0 84-40 84-86v-512c0-46-38-86-84-86h-684c-46 0-84 40-84 86v512c0 46 38 86 84 86h684z" />
|
||||
<glyph unicode="" glyph-name="cancel" d="M726 272.667l-154 154 154 154-60 60-154-154-154 154-60-60 154-154-154-154 60-60 154 154 154-154zM512 852.667c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
|
||||
<glyph unicode="" glyph-name="close" d="M810 664.667l-238-238 238-238-60-60-238 238-238-238-60 60 238 238-238 238 60 60 238-238 238 238z" />
|
||||
<glyph unicode="" glyph-name="asc" d="M512 596.667l256-256-60-60-196 196-196-196-60 60z" />
|
||||
<glyph unicode="" glyph-name="desc" d="M708 572.667l60-60-256-256-256 256 60 60 196-196z" />
|
||||
<glyph unicode="" glyph-name="dots" d="M512 512.667c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM768 512.667c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86zM256 512.667c46 0 86-40 86-86s-40-86-86-86-86 40-86 86 40 86 86 86z" />
|
||||
<glyph unicode="" glyph-name="paused" d="M768 312.667l-382 402c10 4 20 10 30 14h2l12 6c6 2 12 2 18 4v30c0 36 28 64 64 64s64-28 64-64v-30c122-30 192-138 192-270v-156zM512 0.667c-48 0-86 36-86 84h172c0-48-38-84-86-84zM334 676.667c187.235-193.432 375.34-385.994 562-580l-54-54-86 86h-586v42l86 86v214c0 54 12 104 34 146l-120 118 54 56z" />
|
||||
<glyph unicode="" glyph-name="down" d="M512 0.667c-48 0-86 38-86 84h170c0-49.675-37.225-84-84-84zM768 468.667v-212l86-86v-42h-684v42l86 86v212c0 132 70 240 192 270v30c0 36 28 64 64 64s64-28 64-64v-30c122-30 192-140 192-270zM852 490.667c-6 114-64 212-150 274l60 60c102-78 170-198 176-334h-86zM324 764.667c-88-62-146-160-152-274h-86c6 136 74 256 176 334z" />
|
||||
<glyph unicode="" glyph-name="up" d="M426 212.667l384 384-60 62-324-324-152 152-60-60zM512 852.667c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
|
||||
<glyph unicode="" glyph-name="ok" d="M426 212.667l384 384-60 62-324-324-152 152-60-60zM512 852.667c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
|
||||
<glyph unicode="" glyph-name="delete" d="M810 768.667v-86h-596v86h148l44 42h212l44-42h148zM256 128.667v512h512v-512c0-46-40-86-86-86h-340c-46 0-86 40-86 86z" />
|
||||
<glyph unicode="" glyph-name="paused" d="M768 312.667l-382 402c10 4 20 10 30 14h2l12 6c6 2 12 2 18 4v30c0 36 28 64 64 64s64-28 64-64v-30c122-30 192-138 192-270v-156zM512 0.667c-48 0-86 36-86 84h172c0-48-38-84-86-84zM334 676.667c187.235-193.432 375.34-385.994 562-580l-54-54-86 86h-586v42l86 86v214c0 54 12 104 34 146l-120 118 54 56z" />
|
||||
<glyph unicode="" glyph-name="down" d="M512 0.667c-48 0-86 38-86 84h170c0-49.675-37.225-84-84-84zM768 468.667v-212l86-86v-42h-684v42l86 86v212c0 132 70 240 192 270v30c0 36 28 64 64 64s64-28 64-64v-30c122-30 192-140 192-270zM852 490.667c-6 114-64 212-150 274l60 60c102-78 170-198 176-334h-86zM324 764.667c-88-62-146-160-152-274h-86c6 136 74 256 176 334z" />
|
||||
<glyph unicode="" glyph-name="settings" d="M512 276.667c82 0 150 68 150 150s-68 150-150 150-150-68-150-150 68-150 150-150zM830 384.667l90-70c8-6 10-18 4-28l-86-148c-6-10-16-12-26-8l-106 42c-22-16-46-32-72-42l-16-112c-2-10-10-18-20-18h-172c-10 0-18 8-20 18l-16 112c-26 10-50 24-72 42l-106-42c-10-4-20-2-26 8l-86 148c-6 10-4 22 4 28l90 70c-2 14-2 28-2 42s0 28 2 42l-90 70c-8 6-10 18-4 28l86 148c6 10 16 12 26 8l106-42c22 16 46 32 72 42l16 112c2 10 10 18 20 18h172c10 0 18-8 20-18l16-112c26-10 50-24 72-42l106 42c10 4 20 2 26-8l86-148c6-10 4-22-4-28l-90-70c2-14 2-28 2-42s0-28-2-42z" />
|
||||
<glyph unicode="" glyph-name="clippy" horiz-adv-x="896" d="M704 64h-640v576h640v-192h64v320c0 35-29 64-64 64h-192c0 71-57 128-128 128s-128-57-128-128h-192c-35 0-64-29-64-64v-704c0-35 29-64 64-64h640c35 0 64 29 64 64v128h-64v-128zM192 768c29 0 29 0 64 0s64 29 64 64 29 64 64 64 64-29 64-64 32-64 64-64 33 0 64 0 64-29 64-64h-512c0 39 28 64 64 64zM128 256h128v64h-128v-64zM576 384v128l-256-192 256-192v128h320v128h-320zM128 128h192v64h-192v-64zM448 576h-320v-64h320v64zM256 448h-128v-64h128v64z" />
|
||||
<glyph unicode="" glyph-name="mail" d="M512 468.667l342 214h-684zM854 170.667v426l-342-212-342 212v-426h684zM854 768.667c46 0 84-40 84-86v-512c0-46-38-86-84-86h-684c-46 0-84 40-84 86v512c0 46 38 86 84 86h684z" />
|
||||
<glyph unicode="" glyph-name="delete" d="M810 768.667v-86h-596v86h148l44 42h212l44-42h148zM256 128.667v512h512v-512c0-46-40-86-86-86h-340c-46 0-86 40-86 86z" />
|
||||
<glyph unicode="" glyph-name="up" d="M426 212.667l384 384-60 62-324-324-152 152-60-60zM512 852.667c236 0 426-190 426-426s-190-426-426-426-426 190-426 426 190 426 426 426z" />
|
||||
<glyph unicode="" glyph-name="clippy" horiz-adv-x="896" d="M704 64h-640v576h640v-192h64v320c0 35-29 64-64 64h-192c0 71-57 128-128 128s-128-57-128-128h-192c-35 0-64-29-64-64v-704c0-35 29-64 64-64h640c35 0 64 29 64 64v128h-64v-128zM192 768c29 0 29 0 64 0s64 29 64 64 29 64 64 64 64-29 64-64 32-64 64-64 33 0 64 0 64-29 64-64h-512c0 39 28 64 64 64zM128 256h128v64h-128v-64zM576 384v128l-256-192 256-192v128h320v128h-320zM128 128h192v64h-192v-64zM448 576h-320v-64h320v64zM256 448h-128v-64h128v64z" />
|
||||
</font></defs></svg>
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Binary file not shown.
Binary file not shown.
@ -17,7 +17,7 @@
|
||||
</div>
|
||||
{% if tags %}
|
||||
<div id="my-checks-tags" class="col-sm-12">
|
||||
{% for tag, count in tags %}
|
||||
{% for tag in tags %}
|
||||
{% if tag in down_tags %}
|
||||
<button class="btn btn-danger btn-xs" data-toggle="button">{{ tag }}</button>
|
||||
{% elif tag in grace_tags %}
|
||||
|
@ -2,13 +2,29 @@
|
||||
<table id="checks-table" class="table hidden-xs">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th class="th-name">Name</th>
|
||||
<th class="th-name">
|
||||
{% if sort == "name" %}
|
||||
<a href="?sort=-name">Name<span class="icon-asc"></span></a>
|
||||
{% elif sort == "-name" %}
|
||||
<a href="?sort=created">Name<span class="icon-desc"></span></a>
|
||||
{% else %}
|
||||
<a href="?sort=name" class="default">Name</span></a>
|
||||
{% endif %}
|
||||
</th>
|
||||
<th>Ping URL</th>
|
||||
<th class="th-period">
|
||||
Period <br />
|
||||
<span class="checks-subline">Grace</span>
|
||||
</th>
|
||||
<th class="th-last-ping">Last Ping</th>
|
||||
<th class="th-last-ping">
|
||||
{% if sort == "last_ping" %}
|
||||
<a href="?sort=created">Last Ping<span class="icon-desc"></span></a>
|
||||
{% elif sort == "-last_ping" %}
|
||||
<a href="?sort=last_ping">Last Ping<span class="icon-asc"></span></a>
|
||||
{% else %}
|
||||
<a href="?sort=-last_ping" class="default">Last Ping</span></a>
|
||||
{% endif %}
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
{% for check in checks %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user