Browse Source

In the checks list, indicate a started check with a progress spinner under the status icon (cc: #338)

pull/394/head
Pēteris Caune 4 years ago
parent
commit
149096811d
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
10 changed files with 75 additions and 15 deletions
  1. +2
    -2
      CHANGELOG.md
  2. +3
    -3
      hc/api/models.py
  3. +2
    -2
      hc/api/tests/test_check_model.py
  4. +2
    -2
      hc/front/templatetags/hc_extras.py
  5. +3
    -2
      hc/front/views.py
  6. +48
    -0
      static/css/base.css
  7. +6
    -0
      static/js/checks.js
  8. +1
    -1
      templates/front/details.html
  9. +1
    -1
      templates/front/log_status_text.html
  10. +7
    -2
      templates/front/my_checks_desktop.html

+ 2
- 2
CHANGELOG.md View File

@ -1,7 +1,7 @@
# Changelog
All notable changes to this project will be documented in this file.
## Unreleased
## v1.16.0-dev - Unreleased
### Improvements
- Paused ping handling can be controlled via API (#376)
@ -9,7 +9,7 @@ All notable changes to this project will be documented in this file.
- The /api/v1/checks/ endpoint now accepts either UUID or `unique_key` (#370)
- Added /api/v1/checks/uuid/flips/ endpoint (#349)
- In the cron expression dialog, show a human-friendly version of the expression
- Indicate a started check with a progress spinner under status icon (#338)
### Bug Fixes
- Removing Pager Team integration, project appears to be discontinued


+ 3
- 3
hc/api/models.py View File

@ -119,7 +119,7 @@ class Check(models.Model):
if self.last_duration and self.last_duration < MAX_DELTA:
return self.last_duration
def get_grace_start(self):
def get_grace_start(self, with_started=True):
""" Return the datetime when the grace period starts.
If the check is currently new, paused or down, return None.
@ -142,7 +142,7 @@ class Check(models.Model):
it = croniter(self.schedule, last_local)
result = it.next(datetime)
if self.last_start and self.status != "down":
if with_started and self.last_start and self.status != "down":
result = min(result, self.last_start)
if result != NEVER:
@ -175,7 +175,7 @@ class Check(models.Model):
if self.status in ("new", "paused", "down"):
return self.status
grace_start = self.get_grace_start()
grace_start = self.get_grace_start(with_started=with_started)
grace_end = grace_start + self.grace
if now >= grace_end:
return "down"


+ 2
- 2
hc/api/tests/test_check_model.py View File

@ -119,8 +119,8 @@ class CheckModelTestCase(BaseTestCase):
check.last_start = timezone.now() - timedelta(minutes=5)
self.assertEqual(check.get_status(with_started=True), "started")
# Starting a check starts the grace period:
self.assertEqual(check.get_status(), "grace")
# A started check still is considered "up":
self.assertEqual(check.get_status(), "up")
def test_get_status_handles_up_then_started_and_expired(self):
check = Check(status="up")


+ 2
- 2
hc/front/templatetags/hc_extras.py View File

@ -87,7 +87,7 @@ def last_ping_key(check):
def not_down_key(check):
return check.get_status(with_started=True) != "down"
return check.get_status() != "down"
@register.filter
@ -126,7 +126,7 @@ def down_title(check):
"""
s = "%s%s" % (check.name_then_code(), settings.SITE_NAME)
if check.get_status(with_started=True) == "down":
if check.get_status() == "down":
s = "DOWN – " + s
return s


+ 3
- 2
hc/front/views.py View File

@ -207,8 +207,9 @@ def status(request, code):
details.append(
{
"code": str(check.code),
"status": check.get_status(with_started=True),
"status": check.get_status(),
"last_ping": LAST_PING_TMPL.render(ctx),
"started": check.last_start is not None,
}
)
@ -594,7 +595,7 @@ def copy(request, code):
def status_single(request, code):
check = _get_check_for_user(request, code)
status = check.get_status(with_started=True)
status = check.get_status()
events = _get_events(check, 20)
updated = "1"
if len(events):


+ 48
- 0
static/css/base.css View File

@ -168,3 +168,51 @@ pre {
overflow: hidden;
text-overflow: ellipsis;
}
.spinner {
display: none;
width: 24px;
height: 8px;
margin: 4px auto 0 auto;
}
.spinner.started {
display: block;
}
.spinner > div {
float: left;
width: 4px;
height: 4px;
margin: 0 2px;
background: #AAA;
border-radius: 2px;
animation-duration: 1s;
animation-name: spinner-pulse;
animation-iteration-count: infinite;
}
.spinner .d2 {
animation-delay: 0.15s;
}
.spinner .d3 {
animation-delay: 0.3s;
}
@keyframes spinner-pulse {
from {
opacity: 0;
}
50% {
opacity: 1;
}
to {
opacity: 0;
}
}

+ 6
- 0
static/js/checks.js View File

@ -199,6 +199,7 @@ $(function () {
// Schedule refresh to run every 3s when tab is visible and user
// is active, every 60s otherwise
var lastStatus = {};
var lastStarted = {};
var lastPing = {};
var statusUrl = $("#checks-table").data("status-url");
function refreshStatus() {
@ -213,6 +214,11 @@ $(function () {
$("#" + el.code + " span.status").attr("class", "status icon-" + el.status);
}
if (lastStarted[el.code] != el.started) {
lastStarted[el.code] = el.started;
$("#" + el.code + " .spinner").toggleClass("started", el.started);
}
if (lastPing[el.code] != el.last_ping) {
lastPing[el.code] = el.last_ping;
$("#lpd-" + el.code).html(el.last_ping);


+ 1
- 1
templates/front/details.html View File

@ -111,7 +111,7 @@
<table>
<tr>
<td>
<span id="log-status-icon" class="status icon-{{ check.get_status_with_started }}"></span>
<span id="log-status-icon" class="status icon-{{ check.get_status }}"></span>
</td>
<td >
<p id="log-status-text">{% include "front/log_status_text.html" %}</p>


+ 1
- 1
templates/front/log_status_text.html View File

@ -1,5 +1,5 @@
{% load humanize %}
{% with check.get_status_with_started as status %}
{% with check.get_status as status %}
{% if status == "down" %}
This check is down. Last ping was {{ check.last_ping|naturaltime }}.
{% elif status == "up" %}


+ 7
- 2
templates/front/my_checks_desktop.html View File

@ -1,4 +1,4 @@
{% load hc_extras %}
{% load hc_extras static %}
<table
id="checks-table"
class="table"
@ -60,7 +60,12 @@
{% if check in hidden_checks %}style="display: none"{% endif %}>
<td class="indicator-cell">
<span class="status icon-{{ check.get_status_with_started }}" data-toggle="tooltip"></span>
<span class="status icon-{{ check.get_status }}" data-toggle="tooltip"></span>
<div class="spinner {% if check.last_start %}started{% endif %}">
<div class="d1"></div>
<div class="d2"></div>
<div class="d3"></div>
</div>
</td>
<td>
<div data-name="{{ check.name }}"


Loading…
Cancel
Save