mirror of
https://github.com/healthchecks/healthchecks.git
synced 2025-04-07 06:05:34 +00:00
Add date filters in the Log page
This commit is contained in:
parent
1b7bdea9e9
commit
37bbe5a9c7
10 changed files with 209 additions and 45 deletions
|
@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
|
||||||
- Add support for EMAIL_USE_SSL environment variable (#685)
|
- Add support for EMAIL_USE_SSL environment variable (#685)
|
||||||
- Switch from requests to pycurl
|
- Switch from requests to pycurl
|
||||||
- Implement documentation search
|
- Implement documentation search
|
||||||
|
- Add date filters in the Log page
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
- Fix the handling of TooManyRedirects exceptions
|
- Fix the handling of TooManyRedirects exceptions
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from datetime import timedelta as td
|
from datetime import datetime, timedelta as td, timezone
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
from urllib.parse import quote, urlencode
|
from urllib.parse import quote, urlencode
|
||||||
|
@ -337,3 +337,14 @@ class AddGotifyForm(forms.Form):
|
||||||
|
|
||||||
class SearchForm(forms.Form):
|
class SearchForm(forms.Form):
|
||||||
q = forms.RegexField(regex=r"^[0-9a-zA-Z\s]{3,100}$")
|
q = forms.RegexField(regex=r"^[0-9a-zA-Z\s]{3,100}$")
|
||||||
|
|
||||||
|
|
||||||
|
class SeekForm(forms.Form):
|
||||||
|
start = forms.IntegerField()
|
||||||
|
end = forms.IntegerField()
|
||||||
|
|
||||||
|
def clean_start(self):
|
||||||
|
return datetime.fromtimestamp(self.cleaned_data["start"], tz=timezone.utc)
|
||||||
|
|
||||||
|
def clean_end(self):
|
||||||
|
return datetime.fromtimestamp(self.cleaned_data["end"], tz=timezone.utc)
|
||||||
|
|
|
@ -680,9 +680,26 @@ def remove_check(request, code):
|
||||||
return redirect("hc-checks", project.code)
|
return redirect("hc-checks", project.code)
|
||||||
|
|
||||||
|
|
||||||
def _get_events(check, limit):
|
def _get_min(check):
|
||||||
pings = Ping.objects.filter(owner=check).order_by("-id")[:limit]
|
min_n = check.n_pings - check.project.owner_profile.ping_log_limit
|
||||||
pings = list(pings)
|
ping = check.ping_set.filter(n__gt=min_n).first()
|
||||||
|
dt = ping.created if ping else now()
|
||||||
|
return (dt - td(hours=24)).replace(minute=0, second=0)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_total(check, start, end):
|
||||||
|
ping_log_limit = check.project.owner_profile.ping_log_limit
|
||||||
|
pings = check.ping_set.filter(created__gte=start, created__lte=end)
|
||||||
|
return min(pings.count(), ping_log_limit)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_events(check, page_limit, start=None, end=None):
|
||||||
|
min_n = check.n_pings - check.project.owner_profile.ping_log_limit
|
||||||
|
pings = check.ping_set.filter(n__gt=min_n).order_by("-id")
|
||||||
|
if start and end:
|
||||||
|
pings = pings.filter(created__gte=start, created__lte=end)
|
||||||
|
|
||||||
|
pings = list(pings[:page_limit])
|
||||||
|
|
||||||
last_start = None
|
last_start = None
|
||||||
for ping in reversed(pings):
|
for ping in reversed(pings):
|
||||||
|
@ -694,12 +711,15 @@ def _get_events(check, limit):
|
||||||
if delta < MAX_DELTA:
|
if delta < MAX_DELTA:
|
||||||
setattr(ping, "delta", delta)
|
setattr(ping, "delta", delta)
|
||||||
|
|
||||||
alerts = []
|
alerts = Notification.objects.select_related("channel")
|
||||||
if len(pings):
|
alerts = alerts.filter(owner=check, check_status="down")
|
||||||
|
if start and end:
|
||||||
|
alerts = alerts.filter(created__gte=start, created__lte=end)
|
||||||
|
elif len(pings):
|
||||||
cutoff = pings[-1].created
|
cutoff = pings[-1].created
|
||||||
alerts = Notification.objects.select_related("channel").filter(
|
alerts = alerts.filter(created__gt=cutoff)
|
||||||
owner=check, check_status="down", created__gt=cutoff
|
else:
|
||||||
)
|
alerts = []
|
||||||
|
|
||||||
events = pings + list(alerts)
|
events = pings + list(alerts)
|
||||||
events.sort(key=lambda el: el.created, reverse=True)
|
events.sort(key=lambda el: el.created, reverse=True)
|
||||||
|
@ -710,13 +730,26 @@ def _get_events(check, limit):
|
||||||
def log(request, code):
|
def log(request, code):
|
||||||
check, rw = _get_check_for_user(request, code)
|
check, rw = _get_check_for_user(request, code)
|
||||||
|
|
||||||
limit = check.project.owner_profile.ping_log_limit
|
form = forms.SeekForm(request.GET)
|
||||||
|
smin, smax = _get_min(check), now()
|
||||||
|
|
||||||
|
if form.is_valid():
|
||||||
|
start = form.cleaned_data["start"]
|
||||||
|
end = form.cleaned_data["end"]
|
||||||
|
else:
|
||||||
|
start = smin
|
||||||
|
end = smax
|
||||||
|
|
||||||
ctx = {
|
ctx = {
|
||||||
|
"page": "log",
|
||||||
"project": check.project,
|
"project": check.project,
|
||||||
"check": check,
|
"check": check,
|
||||||
"events": _get_events(check, limit),
|
"min": smin,
|
||||||
"limit": limit,
|
"max": smax,
|
||||||
"show_limit_notice": check.n_pings > limit and settings.USE_PAYMENTS,
|
"start": start,
|
||||||
|
"end": end,
|
||||||
|
"events": _get_events(check, 1000, start=start, end=end),
|
||||||
|
"num_total": _get_total(check, start, end),
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, "front/log.html", ctx)
|
return render(request, "front/log.html", ctx)
|
||||||
|
|
|
@ -75,3 +75,21 @@
|
||||||
#log tr.missing td:nth-child(4) {
|
#log tr.missing td:nth-child(4) {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#log-slider {
|
||||||
|
margin-bottom: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#log-slider .noUi-value {
|
||||||
|
font-size: 12px;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#log-slider .noUi-connect {
|
||||||
|
background-color: var(--link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#slider-from-formatted,
|
||||||
|
#slider-to-formatted {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
|
@ -132,7 +132,7 @@
|
||||||
margin: 20px 50px 90px 50px;
|
margin: 20px 50px 90px 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#period-slider.noUi-connect {
|
#period-slider .noUi-connect {
|
||||||
background: #22bc66;
|
background: #22bc66;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,13 +140,13 @@
|
||||||
margin: 20px 50px 110px 50px;
|
margin: 20px 50px 110px 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#grace-slider.noUi-connect {
|
#grace-slider .noUi-connect {
|
||||||
background: #f0ad4e;
|
background: #f0ad4e;
|
||||||
}
|
}
|
||||||
|
|
||||||
#period-slider .noUi-value, #grace-slider .noUi-value {
|
#period-slider .noUi-value, #grace-slider .noUi-value {
|
||||||
width: 60px;
|
font-size: 12px;
|
||||||
margin-left: -30px;
|
padding-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-timeout-terms {
|
.update-timeout-terms {
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
body.dark .noUi-background {
|
|
||||||
background-color: #3c3939;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
body.dark .noUi-target {
|
body.dark .noUi-target {
|
||||||
|
background-color: #3c3939;
|
||||||
border-color: #515151;
|
border-color: #515151;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
@ -25,3 +21,7 @@ body.dark .noUi-marker {
|
||||||
body.dark .noUi-pips {
|
body.dark .noUi-pips {
|
||||||
color: hsl(240, 3%, 55%);
|
color: hsl(240, 3%, 55%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.dark .noUi-value-sub {
|
||||||
|
color: hsl(240, 3%, 45%);
|
||||||
|
}
|
||||||
|
|
5
static/css/nouislider.min.css
vendored
5
static/css/nouislider.min.css
vendored
|
@ -1,4 +1 @@
|
||||||
/*! nouislider - 8.0.2 - 2015-07-06 13:22:09 */
|
.noUi-target,.noUi-target *{-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;-ms-touch-action:none;touch-action:none;-ms-user-select:none;-moz-user-select:none;user-select:none;-moz-box-sizing:border-box;box-sizing:border-box}.noUi-target{position:relative}.noUi-base,.noUi-connects{width:100%;height:100%;position:relative;z-index:1}.noUi-connects{overflow:hidden;z-index:0}.noUi-connect,.noUi-origin{will-change:transform;position:absolute;z-index:1;top:0;right:0;height:100%;width:100%;-ms-transform-origin:0 0;-webkit-transform-origin:0 0;-webkit-transform-style:preserve-3d;transform-origin:0 0;transform-style:flat}.noUi-txt-dir-rtl.noUi-horizontal .noUi-origin{left:0;right:auto}.noUi-vertical .noUi-origin{top:-100%;width:0}.noUi-horizontal .noUi-origin{height:0}.noUi-handle{-webkit-backface-visibility:hidden;backface-visibility:hidden;position:absolute}.noUi-touch-area{height:100%;width:100%}.noUi-state-tap .noUi-connect,.noUi-state-tap .noUi-origin{-webkit-transition:transform .3s;transition:transform .3s}.noUi-state-drag *{cursor:inherit!important}.noUi-horizontal{height:18px}.noUi-horizontal .noUi-handle{width:34px;height:28px;right:-17px;top:-6px}.noUi-vertical{width:18px}.noUi-vertical .noUi-handle{width:28px;height:34px;right:-6px;bottom:-17px}.noUi-txt-dir-rtl.noUi-horizontal .noUi-handle{left:-17px;right:auto}.noUi-target{background:#FAFAFA;border-radius:4px;border:1px solid #D3D3D3;box-shadow:inset 0 1px 1px #F0F0F0,0 3px 6px -5px #BBB}.noUi-connects{border-radius:3px}.noUi-connect{background:#3FB8AF}.noUi-draggable{cursor:ew-resize}.noUi-vertical .noUi-draggable{cursor:ns-resize}.noUi-handle{border:1px solid #D9D9D9;border-radius:3px;background:#FFF;cursor:default;box-shadow:inset 0 0 1px #FFF,inset 0 1px 7px #EBEBEB,0 3px 6px -3px #BBB}.noUi-active{box-shadow:inset 0 0 1px #FFF,inset 0 1px 7px #DDD,0 3px 6px -3px #BBB}.noUi-handle:after,.noUi-handle:before{content:"";display:block;position:absolute;height:14px;width:1px;background:#E8E7E6;left:14px;top:6px}.noUi-handle:after{left:17px}.noUi-vertical .noUi-handle:after,.noUi-vertical .noUi-handle:before{width:14px;height:1px;left:6px;top:14px}.noUi-vertical .noUi-handle:after{top:17px}[disabled] .noUi-connect{background:#B8B8B8}[disabled] .noUi-handle,[disabled].noUi-handle,[disabled].noUi-target{cursor:not-allowed}.noUi-pips,.noUi-pips *{-moz-box-sizing:border-box;box-sizing:border-box}.noUi-pips{position:absolute;color:#999}.noUi-value{position:absolute;white-space:nowrap;text-align:center}.noUi-value-sub{color:#ccc;font-size:10px}.noUi-marker{position:absolute;background:#CCC}.noUi-marker-sub{background:#AAA}.noUi-marker-large{background:#AAA}.noUi-pips-horizontal{padding:10px 0;height:80px;top:100%;left:0;width:100%}.noUi-value-horizontal{-webkit-transform:translate(-50%,50%);transform:translate(-50%,50%)}.noUi-rtl .noUi-value-horizontal{-webkit-transform:translate(50%,50%);transform:translate(50%,50%)}.noUi-marker-horizontal.noUi-marker{margin-left:-1px;width:2px;height:5px}.noUi-marker-horizontal.noUi-marker-sub{height:10px}.noUi-marker-horizontal.noUi-marker-large{height:15px}.noUi-pips-vertical{padding:0 10px;height:100%;top:0;left:100%}.noUi-value-vertical{-webkit-transform:translate(0,-50%);transform:translate(0,-50%);padding-left:25px}.noUi-rtl .noUi-value-vertical{-webkit-transform:translate(0,50%);transform:translate(0,50%)}.noUi-marker-vertical.noUi-marker{width:5px;height:2px;margin-top:-1px}.noUi-marker-vertical.noUi-marker-sub{width:10px}.noUi-marker-vertical.noUi-marker-large{width:15px}.noUi-tooltip{display:block;position:absolute;border:1px solid #D9D9D9;border-radius:3px;background:#fff;color:#000;padding:5px;text-align:center;white-space:nowrap}.noUi-horizontal .noUi-tooltip{-webkit-transform:translate(-50%,0);transform:translate(-50%,0);left:50%;bottom:120%}.noUi-vertical .noUi-tooltip{-webkit-transform:translate(0,-50%);transform:translate(0,-50%);top:50%;right:120%}.noUi-horizontal .noUi-origin>.noUi-tooltip{-webkit-transform:translate(50%,0);transform:translate(50%,0);left:auto;bottom:10px}.noUi-vertical .noUi-origin>.noUi-tooltip{-webkit-transform:translate(0,-18px);transform:translate(0,-18px);top:auto;right:28px}
|
||||||
|
|
||||||
|
|
||||||
.noUi-target,.noUi-target *{-webkit-touch-callout:none;-webkit-user-select:none;-ms-touch-action:none;-ms-user-select:none;-moz-user-select:none;-moz-box-sizing:border-box;box-sizing:border-box}.noUi-target{position:relative;direction:ltr}.noUi-base{width:100%;height:100%;position:relative;z-index:1}.noUi-origin{position:absolute;right:0;top:0;left:0;bottom:0}.noUi-handle{position:relative;z-index:1}.noUi-stacking .noUi-handle{z-index:10}.noUi-state-tap .noUi-origin{-webkit-transition:left .3s,top .3s;transition:left .3s,top .3s}.noUi-state-drag *{cursor:inherit!important}.noUi-base{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.noUi-horizontal{height:18px}.noUi-horizontal .noUi-handle{width:34px;height:28px;left:-17px;top:-6px}.noUi-vertical{width:18px}.noUi-vertical .noUi-handle{width:28px;height:34px;left:-6px;top:-17px}.noUi-background{background:#FAFAFA;box-shadow:inset 0 1px 1px #f0f0f0}.noUi-connect{background:#3FB8AF;box-shadow:inset 0 0 3px rgba(51,51,51,.45);-webkit-transition:background 450ms;transition:background 450ms}.noUi-origin{border-radius:2px}.noUi-target{border-radius:4px;border:1px solid #D3D3D3;box-shadow:inset 0 1px 1px #F0F0F0,0 3px 6px -5px #BBB}.noUi-target.noUi-connect{box-shadow:inset 0 0 3px rgba(51,51,51,.45),0 3px 6px -5px #BBB}.noUi-dragable{cursor:w-resize}.noUi-vertical .noUi-dragable{cursor:n-resize}.noUi-handle{border:1px solid #D9D9D9;border-radius:3px;background:#FFF;cursor:default;box-shadow:inset 0 0 1px #FFF,inset 0 1px 7px #EBEBEB,0 3px 6px -3px #BBB}.noUi-active{box-shadow:inset 0 0 1px #FFF,inset 0 1px 7px #DDD,0 3px 6px -3px #BBB}.noUi-handle:after,.noUi-handle:before{content:"";display:block;position:absolute;height:14px;width:1px;background:#E8E7E6;left:14px;top:6px}.noUi-handle:after{left:17px}.noUi-vertical .noUi-handle:after,.noUi-vertical .noUi-handle:before{width:14px;height:1px;left:6px;top:14px}.noUi-vertical .noUi-handle:after{top:17px}[disabled] .noUi-connect,[disabled].noUi-connect{background:#B8B8B8}[disabled] .noUi-handle,[disabled].noUi-origin{cursor:not-allowed}.noUi-pips,.noUi-pips *{-moz-box-sizing:border-box;box-sizing:border-box}.noUi-pips{position:absolute;font:400 12px Arial;color:#999}.noUi-value{width:40px;position:absolute;text-align:center}.noUi-value-sub{color:#ccc;font-size:10px}.noUi-marker{position:absolute;background:#CCC}.noUi-marker-large,.noUi-marker-sub{background:#AAA}.noUi-pips-horizontal{padding:10px 0;height:50px;top:100%;left:0;width:100%}.noUi-value-horizontal{margin-left:-20px;padding-top:20px}.noUi-value-horizontal.noUi-value-sub{padding-top:15px}.noUi-marker-horizontal.noUi-marker{margin-left:-1px;width:2px;height:5px}.noUi-marker-horizontal.noUi-marker-sub{height:10px}.noUi-marker-horizontal.noUi-marker-large{height:15px}.noUi-pips-vertical{padding:0 10px;height:100%;top:0;left:100%}.noUi-value-vertical{width:15px;margin-left:20px;margin-top:-5px}.noUi-marker-vertical.noUi-marker{width:5px;height:2px;margin-top:-1px}.noUi-marker-vertical.noUi-marker-sub{width:10px}.noUi-marker-vertical.noUi-marker-large{width:15px}
|
|
100
static/js/log.js
100
static/js/log.js
|
@ -1,4 +1,96 @@
|
||||||
$(function () {
|
$(function () {
|
||||||
|
var SMALL_LABEL = 2;
|
||||||
|
var BIG_LABEL = 1;
|
||||||
|
var PIP = 0;
|
||||||
|
var NO_PIP = -1;
|
||||||
|
|
||||||
|
var slider = document.getElementById("log-slider");
|
||||||
|
var smin = parseInt(slider.dataset.min);
|
||||||
|
var smax = parseInt(slider.dataset.max);
|
||||||
|
var deltaHours = (smax - smin) / 3600;
|
||||||
|
var pixelsPerHour = slider.clientWidth / deltaHours;
|
||||||
|
var pixelsPerDay = pixelsPerHour * 24;
|
||||||
|
var dayGap = Math.round(0.5 + 80 / pixelsPerDay);
|
||||||
|
|
||||||
|
var dateFormat = "local";
|
||||||
|
function fromUnix(timestamp) {
|
||||||
|
var dt = moment.unix(timestamp);
|
||||||
|
dateFormat == "local" ? dt.local() : dt.tz(dateFormat);
|
||||||
|
return dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterPips(value, type) {
|
||||||
|
var m = fromUnix(value);
|
||||||
|
if (m.minute() != 0)
|
||||||
|
return NO_PIP;
|
||||||
|
|
||||||
|
// Date labels on every day
|
||||||
|
if (pixelsPerDay > 60 && m.hour() == 0)
|
||||||
|
return BIG_LABEL;
|
||||||
|
|
||||||
|
// Date labels every "dayGap" days
|
||||||
|
if (m.hour() == 0 && m.dayOfYear() % dayGap == 0)
|
||||||
|
return BIG_LABEL;
|
||||||
|
|
||||||
|
// Hour labels on every hour:
|
||||||
|
if (pixelsPerHour > 40)
|
||||||
|
return SMALL_LABEL;
|
||||||
|
|
||||||
|
// Hour labels every 3 hours:
|
||||||
|
if (pixelsPerHour > 15 && m.hour() % 3 == 0)
|
||||||
|
return SMALL_LABEL;
|
||||||
|
|
||||||
|
// Hour labels every 6 hours:
|
||||||
|
if (pixelsPerHour > 5 && m.hour() % 6 == 0)
|
||||||
|
return SMALL_LABEL;
|
||||||
|
|
||||||
|
// Pip on every hour
|
||||||
|
if (pixelsPerHour > 5)
|
||||||
|
return PIP;
|
||||||
|
|
||||||
|
// Pip on every day
|
||||||
|
if (pixelsPerDay > 10 && m.hour() == 0)
|
||||||
|
return PIP;
|
||||||
|
|
||||||
|
return NO_PIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fmt(ts) {
|
||||||
|
var pipType = filterPips(ts);
|
||||||
|
return fromUnix(ts).format(pipType == 2 ? "HH:mm" : "MMM D");
|
||||||
|
}
|
||||||
|
|
||||||
|
noUiSlider.create(slider, {
|
||||||
|
start: [parseInt(slider.dataset.start), parseInt(slider.dataset.end)],
|
||||||
|
range: {'min': smin, 'max': smax},
|
||||||
|
connect: true,
|
||||||
|
step: 3600,
|
||||||
|
pips: {
|
||||||
|
mode: "steps",
|
||||||
|
density: 3,
|
||||||
|
filter: filterPips,
|
||||||
|
format: {
|
||||||
|
to: fmt,
|
||||||
|
from: function() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateSliderPreview() {
|
||||||
|
var values = slider.noUiSlider.get();
|
||||||
|
$("#slider-from-formatted").text(fromUnix(values[0]).format("MMMM D, HH:mm"));
|
||||||
|
$("#slider-to-formatted").text(fromUnix(values[1]).format("MMMM D, HH:mm"));
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSliderPreview();
|
||||||
|
slider.noUiSlider.on("slide", updateSliderPreview);
|
||||||
|
|
||||||
|
slider.noUiSlider.on("change", function(a, b, value) {
|
||||||
|
$("#seek-start").val(Math.round(value[0]));
|
||||||
|
$("#seek-end").val(Math.round(value[1]));
|
||||||
|
$("#seek-form").submit();
|
||||||
|
});
|
||||||
|
|
||||||
$("#log tr.ok").on("click", function() {
|
$("#log tr.ok").on("click", function() {
|
||||||
var n = $("td", this).first().text();
|
var n = $("td", this).first().text();
|
||||||
var tmpl = $("#log").data("url").slice(0, -2);
|
var tmpl = $("#log").data("url").slice(0, -2);
|
||||||
|
@ -7,10 +99,12 @@ $(function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
function switchDateFormat(format) {
|
function switchDateFormat(format) {
|
||||||
document.querySelectorAll("#log tr").forEach(function(row) {
|
dateFormat = format;
|
||||||
var dt = moment.unix(row.dataset.dt).utc();
|
slider.noUiSlider.updateOptions({}, true);
|
||||||
format == "local" ? dt.local() : dt.tz(format);
|
updateSliderPreview();
|
||||||
|
|
||||||
|
document.querySelectorAll("#log tr").forEach(function(row) {
|
||||||
|
var dt = fromUnix(row.dataset.dt);
|
||||||
row.children[1].textContent = dt.format("MMM D");
|
row.children[1].textContent = dt.format("MMM D");
|
||||||
row.children[2].textContent = dt.format("HH:mm");
|
row.children[2].textContent = dt.format("HH:mm");
|
||||||
})
|
})
|
||||||
|
|
4
static/js/nouislider.min.js
vendored
4
static/js/nouislider.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -35,25 +35,36 @@
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
|
<p>Filter events from <strong id="slider-from-formatted"></strong> to <strong id="slider-to-formatted"></strong>.</p>
|
||||||
|
<div
|
||||||
|
id="log-slider"
|
||||||
|
data-min="{{ min|timestamp }}"
|
||||||
|
data-max="{{ max|timestamp }}"
|
||||||
|
data-start="{{ start|timestamp }}"
|
||||||
|
data-end="{{ end|timestamp }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form id="seek-form" method="get">
|
||||||
|
<input type="hidden" name="start" id="seek-start">
|
||||||
|
<input type="hidden" name="end" id="seek-end">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% if num_total > 1000 %}
|
||||||
|
<p class="alert alert-info">Found {{ num_total }} ping events, displaying the most recent 1000.</p>
|
||||||
|
{% elif num_total > 0 %}
|
||||||
|
<p class="alert alert-info">Found {{ num_total }} ping event{{ num_total|pluralize }}.</p>
|
||||||
|
{% elif not events and check.n_pings > 0 %}
|
||||||
|
<div class="alert alert-info">The filter parameters matched no events.</div>
|
||||||
|
{% elif check.n_pings == 0 %}
|
||||||
|
<div class="alert alert-info">Log is empty. This check has not received any pings yet.</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if events %}
|
{% if events %}
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table" id="log" data-url="{% url 'hc-ping-details' check.code '0' %}">
|
<table class="table" id="log" data-url="{% url 'hc-ping-details' check.code '0' %}">
|
||||||
{% for event in events %}{% include "front/log_row.html" with describe_body=True %}{% endfor %}
|
{% for event in events %}{% include "front/log_row.html" with describe_body=True %}{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if show_limit_notice and limit < 1000 %}
|
|
||||||
<p class="alert alert-info">
|
|
||||||
<strong>Showing last {{ limit }} pings.</strong>
|
|
||||||
Want to see more?
|
|
||||||
<a href="{% url 'hc-pricing' %}">
|
|
||||||
Upgrade your account!
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-info">Log is empty. This check has not received any pings yet.</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -75,6 +86,7 @@
|
||||||
{% compress js %}
|
{% compress js %}
|
||||||
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
|
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
|
||||||
<script src="{% static 'js/bootstrap.min.js' %}"></script>
|
<script src="{% static 'js/bootstrap.min.js' %}"></script>
|
||||||
|
<script src="{% static 'js/nouislider.min.js' %}"></script>
|
||||||
<script src="{% static 'js/moment.min.js' %}"></script>
|
<script src="{% static 'js/moment.min.js' %}"></script>
|
||||||
<script src="{% static 'js/moment-timezone-with-data-10-year-range.min.js' %}"></script>
|
<script src="{% static 'js/moment-timezone-with-data-10-year-range.min.js' %}"></script>
|
||||||
<script src="{% static 'js/purify.min.js' %}"></script>
|
<script src="{% static 'js/purify.min.js' %}"></script>
|
||||||
|
|
Loading…
Add table
Reference in a new issue