forked from GithubBackups/healthchecks
Prepare for auto-refresh in "My Checks" screen.
This commit is contained in:
parent
d05607d73c
commit
1b4ca77096
@ -44,6 +44,7 @@ urlpatterns = [
|
|||||||
url(r'^checks/$', views.my_checks, name="hc-checks"),
|
url(r'^checks/$', views.my_checks, name="hc-checks"),
|
||||||
url(r'^checks/add/$', views.add_check, name="hc-add-check"),
|
url(r'^checks/add/$', views.add_check, name="hc-add-check"),
|
||||||
url(r'^checks/cron_preview/$', views.cron_preview),
|
url(r'^checks/cron_preview/$', views.cron_preview),
|
||||||
|
url(r'^checks/status/$', views.status),
|
||||||
url(r'^checks/([\w-]+)/', include(check_urls)),
|
url(r'^checks/([\w-]+)/', include(check_urls)),
|
||||||
url(r'^integrations/', include(channel_urls)),
|
url(r'^integrations/', include(channel_urls)),
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ from django.contrib.auth.decorators import login_required
|
|||||||
from django.core import signing
|
from django.core import signing
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.http import (Http404, HttpResponse, HttpResponseBadRequest,
|
from django.http import (Http404, HttpResponse, HttpResponseBadRequest,
|
||||||
HttpResponseForbidden)
|
HttpResponseForbidden, JsonResponse)
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
@ -34,6 +34,24 @@ import requests
|
|||||||
VALID_SORT_VALUES = ("name", "-name", "last_ping", "-last_ping", "created")
|
VALID_SORT_VALUES = ("name", "-name", "last_ping", "-last_ping", "created")
|
||||||
|
|
||||||
|
|
||||||
|
def _tags_statuses(checks):
|
||||||
|
tags, down, grace = {}, {}, {}
|
||||||
|
for check in checks:
|
||||||
|
if check.get_status() == "down":
|
||||||
|
for tag in check.tags_list():
|
||||||
|
down[tag] = "down"
|
||||||
|
elif check.in_grace_period():
|
||||||
|
for tag in check.tags_list():
|
||||||
|
grace[tag] = "grace"
|
||||||
|
else:
|
||||||
|
for tag in check.tags_list():
|
||||||
|
tags[tag] = "up"
|
||||||
|
|
||||||
|
tags.update(grace)
|
||||||
|
tags.update(down)
|
||||||
|
return tags
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def my_checks(request):
|
def my_checks(request):
|
||||||
if request.GET.get("sort") in VALID_SORT_VALUES:
|
if request.GET.get("sort") in VALID_SORT_VALUES:
|
||||||
@ -42,35 +60,41 @@ def my_checks(request):
|
|||||||
|
|
||||||
checks = list(Check.objects.filter(user=request.team.user))
|
checks = list(Check.objects.filter(user=request.team.user))
|
||||||
|
|
||||||
tags, down_tags, grace_tags = set(), set(), set()
|
pairs = list(_tags_statuses(checks).items())
|
||||||
for check in checks:
|
pairs.sort(key=lambda pair: pair[0].lower())
|
||||||
status = check.get_status()
|
|
||||||
for tag in check.tags_list():
|
|
||||||
tags.add(tag)
|
|
||||||
|
|
||||||
if status == "down":
|
|
||||||
down_tags.add(tag)
|
|
||||||
elif check.in_grace_period():
|
|
||||||
grace_tags.add(tag)
|
|
||||||
|
|
||||||
can_add_more = len(checks) < request.team.check_limit
|
|
||||||
|
|
||||||
ctx = {
|
ctx = {
|
||||||
"page": "checks",
|
"page": "checks",
|
||||||
"checks": checks,
|
"checks": checks,
|
||||||
"now": timezone.now(),
|
"now": timezone.now(),
|
||||||
"tags": sorted(tags, key=lambda s: s.lower()),
|
"tags": pairs,
|
||||||
"down_tags": down_tags,
|
|
||||||
"grace_tags": grace_tags,
|
|
||||||
"ping_endpoint": settings.PING_ENDPOINT,
|
"ping_endpoint": settings.PING_ENDPOINT,
|
||||||
"timezones": all_timezones,
|
"timezones": all_timezones,
|
||||||
"can_add_more": can_add_more,
|
"can_add_more": len(checks) < request.team.check_limit,
|
||||||
"sort": request.profile.sort
|
"sort": request.profile.sort
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, "front/my_checks.html", ctx)
|
return render(request, "front/my_checks.html", ctx)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def status(request):
|
||||||
|
checks = list(Check.objects.filter(user=request.team.user))
|
||||||
|
|
||||||
|
details = []
|
||||||
|
for check in checks:
|
||||||
|
status = "grace" if check.in_grace_period() else check.get_status()
|
||||||
|
|
||||||
|
ctx = {"check": check}
|
||||||
|
details.append({
|
||||||
|
"code": str(check.code),
|
||||||
|
"status": status,
|
||||||
|
"last_ping": render_to_string("front/last_ping_cell.html", ctx)
|
||||||
|
})
|
||||||
|
|
||||||
|
return JsonResponse({"details": details, "tags": _tags_statuses(checks)})
|
||||||
|
|
||||||
|
|
||||||
def _welcome_check(request):
|
def _welcome_check(request):
|
||||||
check = None
|
check = None
|
||||||
if "welcome_code" in request.session:
|
if "welcome_code" in request.session:
|
||||||
|
@ -58,7 +58,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.status.icon-up { color: #5cb85c; }
|
.status.icon-up { color: #5cb85c; }
|
||||||
.status.icon-up.new, .status.icon-paused { color: #CCC; }
|
.status.icon-new, .status.icon-paused { color: #CCC; }
|
||||||
.status.icon-grace { color: #f0ad4e; }
|
.status.icon-grace { color: #f0ad4e; }
|
||||||
.status.icon-down { color: #d9534f; }
|
.status.icon-down { color: #d9534f; }
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
.icon-delete:before {
|
.icon-delete:before {
|
||||||
content: "\e901";
|
content: "\e901";
|
||||||
}
|
}
|
||||||
.icon-up:before, .icon-ok:before {
|
.icon-new:before, .icon-up:before, .icon-ok:before {
|
||||||
content: "\e902";
|
content: "\e902";
|
||||||
}
|
}
|
||||||
.icon-clippy:before {
|
.icon-clippy:before {
|
||||||
|
@ -1,3 +1,22 @@
|
|||||||
|
#my-checks-tags button.up {
|
||||||
|
color: #333;
|
||||||
|
background-color: #fff;
|
||||||
|
border-color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#my-checks-tags button.grace {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #f0ad4e;
|
||||||
|
border-color: #eea236;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#my-checks-tags button.down {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #d9534f;
|
||||||
|
border-color: #d43f3a;
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 992px) {
|
@media (min-width: 992px) {
|
||||||
#update-timeout-modal .modal-dialog, #last-ping-modal .modal-dialog {
|
#update-timeout-modal .modal-dialog, #last-ping-modal .modal-dialog {
|
||||||
width: 800px;
|
width: 800px;
|
||||||
|
@ -175,7 +175,7 @@ $(function () {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".last-ping").click(function() {
|
$(".last-ping-cell").on("click", ".last-ping", function() {
|
||||||
$("#last-ping-body").text("Updating...");
|
$("#last-ping-body").text("Updating...");
|
||||||
$('#last-ping-modal').modal("show");
|
$('#last-ping-modal').modal("show");
|
||||||
|
|
||||||
@ -235,7 +235,15 @@ $(function () {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
$('[data-toggle="tooltip"]').tooltip();
|
$('[data-toggle="tooltip"]').tooltip({
|
||||||
|
title: function() {
|
||||||
|
var cssClasses = this.getAttribute("class");
|
||||||
|
if (cssClasses.indexOf("icon-new") > -1)
|
||||||
|
return "New. Has never received a ping.";
|
||||||
|
if (cssClasses.indexOf("icon-paused") > -1)
|
||||||
|
return "Monitoring paused. Ping to resume.";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$(".usage-examples").click(function(e) {
|
$(".usage-examples").click(function(e) {
|
||||||
var a = e.target;
|
var a = e.target;
|
||||||
@ -249,6 +257,24 @@ $(function () {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Auto-refresh
|
||||||
|
function refresh() {
|
||||||
|
$.getJSON("/checks/status/", function(data) {
|
||||||
|
for(var i=0, el; el=data.details[i]; i++) {
|
||||||
|
$("#check-desktop-" + el.code + " .indicator-cell span").attr("class", "status icon-" + el.status);
|
||||||
|
$("#check-desktop-" + el.code + " .last-ping-cell").html(el.last_ping);
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#my-checks-tags button").each(function(a) {
|
||||||
|
var status = data.tags[this.innerText];
|
||||||
|
if (status) {
|
||||||
|
this.setAttribute("class", "btn btn-xs " + status);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy to clipboard
|
||||||
var clipboard = new Clipboard('button.copy-link');
|
var clipboard = new Clipboard('button.copy-link');
|
||||||
$("button.copy-link").mouseout(function(e) {
|
$("button.copy-link").mouseout(function(e) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
|
@ -204,7 +204,7 @@ using the "-command" argument:</p>
|
|||||||
<table class="table">
|
<table class="table">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<span class="status icon-up new"></span>
|
<span class="status icon-new"></span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<strong>New.</strong>
|
<strong>New.</strong>
|
||||||
|
12
templates/front/last_ping_cell.html
Normal file
12
templates/front/last_ping_cell.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{% load humanize %}
|
||||||
|
|
||||||
|
{% if check.last_ping %}
|
||||||
|
<div class="last-ping" data-url="{% url 'hc-last-ping' check.code %}">
|
||||||
|
{{ check.last_ping|naturaltime }}
|
||||||
|
{% if check.has_confirmation_link %}
|
||||||
|
<br /><span class="label label-confirmation">confirmation link</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="last-ping-never">Never</div>
|
||||||
|
{% endif %}
|
@ -17,14 +17,8 @@
|
|||||||
</div>
|
</div>
|
||||||
{% if tags %}
|
{% if tags %}
|
||||||
<div id="my-checks-tags" class="col-sm-12">
|
<div id="my-checks-tags" class="col-sm-12">
|
||||||
{% for tag in tags %}
|
{% for tag, status in tags %}
|
||||||
{% if tag in down_tags %}
|
<button class="btn btn-xs {{ status }}" data-toggle="button">{{ tag }}</button>
|
||||||
<button class="btn btn-danger btn-xs" data-toggle="button">{{ tag }}</button>
|
|
||||||
{% elif tag in grace_tags %}
|
|
||||||
<button class="btn btn-warning btn-xs" data-toggle="button">{{ tag }}</button>
|
|
||||||
{% else %}
|
|
||||||
<button class="btn btn-default btn-xs" data-toggle="button">{{ tag }}</button>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% load hc_extras humanize %}
|
{% load hc_extras %}
|
||||||
<table id="checks-table" class="table hidden-xs">
|
<table id="checks-table" class="table hidden-xs">
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
@ -28,20 +28,12 @@
|
|||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
{% for check in checks|sortchecks:sort %}
|
{% for check in checks|sortchecks:sort %}
|
||||||
<tr class="checks-row">
|
<tr id="check-desktop-{{ check.code }}" class="checks-row">
|
||||||
<td class="indicator-cell">
|
<td class="indicator-cell">
|
||||||
{% if check.get_status == "new" %}
|
{% if check.in_grace_period %}
|
||||||
<span class="status icon-up new"
|
<span class="status icon-grace" data-toggle="tooltip"></span>
|
||||||
data-toggle="tooltip" title="New. Has never received a ping."></span>
|
{% else %}
|
||||||
{% elif check.get_status == "paused" %}
|
<span class="status icon-{{ check.get_status }}" data-toggle="tooltip"></span>
|
||||||
<span class="status icon-paused"
|
|
||||||
data-toggle="tooltip" title="Monitoring paused. Ping to resume."></span>
|
|
||||||
{% elif check.in_grace_period %}
|
|
||||||
<span class="status icon-grace"></span>
|
|
||||||
{% elif check.get_status == "up" %}
|
|
||||||
<span class="status icon-up"></span>
|
|
||||||
{% elif check.get_status == "down" %}
|
|
||||||
<span class="status icon-down"></span>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="name-cell">
|
<td class="name-cell">
|
||||||
@ -85,17 +77,8 @@
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td class="last-ping-cell">
|
||||||
{% if check.last_ping %}
|
{% include "front/last_ping_cell.html" with check=check %}
|
||||||
<div class="last-ping" data-url="{% url 'hc-last-ping' check.code %}">
|
|
||||||
{{ check.last_ping|naturaltime }}
|
|
||||||
{% if check.has_confirmation_link %}
|
|
||||||
<br /><span class="label label-confirmation">confirmation link</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="last-ping-never">Never</div>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="check-menu dropdown">
|
<div class="check-menu dropdown">
|
||||||
|
@ -174,7 +174,7 @@
|
|||||||
<table class="table">
|
<table class="table">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<span class="status icon-up new"></span>
|
<span class="status icon-new"></span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
New.
|
New.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user