Compare commits

..

5 Commits

Author SHA1 Message Date
R. Miles McCain
17bb5cda0d Improve litepicker box shadow 2021-05-14 15:32:16 +00:00
R. Miles McCain
84c647ad43 Update packages 2021-05-14 15:32:08 +00:00
Paweł Jastrzębski
0e37e7f042 Update litepicker and add ranges plugin
Fix litepicker colors

Fix litepicker event

Add custom ranges to litepicker

Fix code style

Remove some date ranges

Fix date ranges

Replace yesterday date range with last 3 days
2021-05-14 15:09:14 +00:00
CasperVerswijvelt
a76e0feaf3 Add custom location url from environment variable
Remove trailing dollar in long and lat placeholder
2021-05-14 15:07:49 +00:00
CasperVerswijvelt
109d977932 Make favicon not squish and add ellipsis overflow
General styling improvements

Many UI Improvements

- Consistent spacing between titles and content
- Removed many ugly text squishing by hiding overflowing text with ellipsis
- Fixed Service favicon being squisched by long service name
- Hide scrollbar in 'more session' screen when content isn't scrollable
- Fix apexcharts tooltips and labels being cut off by card class

Disable wrapping in table cells, prefer ellipsis

Ellipsis overflow for long url on hit page

Fix flex grow in header not working as intended

Remove forgotten truncatechars

Fix code checks, add button role and tabindex
2021-05-14 15:04:30 +00:00
11 changed files with 23 additions and 127 deletions

View File

@@ -1,46 +0,0 @@
name: Build docker images
on:
push:
tags:
- "*"
jobs:
publish_to_docker_hub:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Prepare tags
id: prep
run: |
DOCKER_IMAGE=milesmcc/shynet
VERSION=${GITHUB_REF#refs/tags/}
TAGS="${DOCKER_IMAGE}:${VERSION},${DOCKER_IMAGE}:latest"
echo ::set-output name=tags::${TAGS}
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Build and push advanced image
id: docker_build
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: ${{ steps.prep.outputs.tags }}

View File

@@ -1,4 +1,4 @@
FROM python:alpine3.12
FROM python:3-alpine
# Getting things ready
WORKDIR /usr/src/shynet

View File

@@ -91,8 +91,4 @@ AGGRESSIVE_HASH_SALTING=True
# - https://www.openstreetmap.org/?mlat=$LATITUDE&mlon=$LONGITUDE (default)
# - https://www.google.com/maps/search/?api=1&query=$LATITUDE,$LONGITUDE
# - https://www.mapquest.com/near-$LATITUDE,$LONGITUDE
LOCATION_URL=https://www.openstreetmap.org/?mlat=$LATITUDE&mlon=$LONGITUDE
# How many services should be displayed on dashboard page?
# Set to big number if you don't want pagination at all.
DASHBOARD_PAGE_SIZE=5
LOCATION_URL=https://www.openstreetmap.org/?mlat=$LATITUDE&mlon=$LONGITUDE

View File

@@ -127,11 +127,6 @@
"description": "Custom location url to link to in frontend.",
"value": "https://www.openstreetmap.org/?mlat=$LATITUDE&mlon=$LONGITUDE",
"required": false
},
"DASHBOARD_PAGE_SIZE": {
"description": "How many services should be displayed on dashboard page?",
"value": "5",
"required": false
}
}
}

View File

@@ -8,14 +8,11 @@
var Shynet = {
idempotency: null,
heartbeatTaskId: null,
skipHeartbeat: false,
sendHeartbeat: function () {
try {
if (document.hidden || Shynet.skipHeartbeat) {
if (document.hidden) {
return;
}
Shynet.skipHeartbeat = true;
var xhr = new XMLHttpRequest();
xhr.open(
"POST",
@@ -23,12 +20,6 @@ var Shynet = {
true
);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onload = function () {
Shynet.skipHeartbeat = false;
};
xhr.onerror = function () {
Shynet.skipHeartbeat = false;
};
xhr.send(
JSON.stringify({
idempotency: Shynet.idempotency,
@@ -39,14 +30,13 @@ var Shynet = {
window.performance.timing.navigationStart,
})
);
} catch (e) {}
} catch (e) { }
},
newPageLoad: function () {
if (Shynet.heartbeatTaskId != null) {
clearInterval(Shynet.heartbeatTaskId);
}
Shynet.idempotency = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
Shynet.skipHeartbeat = false;
Shynet.heartbeatTaskId = setInterval(Shynet.sendHeartbeat, parseInt("{{heartbeat_frequency}}"));
Shynet.sendHeartbeat();
}
@@ -61,4 +51,4 @@ window.addEventListener("load", Shynet.newPageLoad);
// -- START --
{{script_inject|safe}}
// -- END --
{% endif %}
{% endif %}

View File

@@ -8,12 +8,12 @@ from django.conf import settings
from django.contrib.auth.models import AbstractUser
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models.functions import TruncDate, TruncHour
from django.db.models.functions import TruncDate
from django.db.utils import NotSupportedError
from django.shortcuts import reverse
from django.utils import timezone
# How long a session a needs to go without an update to no longer be considered 'active' (i.e., currently online)
ACTIVE_USER_TIMEDELTA = timezone.timedelta(
milliseconds=settings.SCRIPT_HEARTBEAT_FREQUENCY * 2
)
@@ -125,10 +125,8 @@ class Service(models.Model):
Session = apps.get_model("analytics", "Session")
Hit = apps.get_model("analytics", "Hit")
tz_now = timezone.now()
currently_online = Session.objects.filter(
service=self, last_seen__gt=tz_now - ACTIVE_USER_TIMEDELTA
service=self, last_seen__gt=timezone.now() - ACTIVE_USER_TIMEDELTA
).count()
sessions = Session.objects.filter(
@@ -212,35 +210,17 @@ class Service(models.Model):
if session_count == 0:
avg_session_duration = None
# Show hourly chart for date ranges of 3 days or less, otherwise daily chart
if (end_time - start_time).days < 3:
session_chart_tooltip_format = "MM/dd HH:mm"
session_chart_granularity = "hourly"
session_chart_data = {
k["hour"]: k["count"]
for k in sessions.annotate(hour=TruncHour("start_time"))
.values("hour")
.annotate(count=models.Count("uuid"))
.order_by("hour")
}
for hour_offset in range(int((end_time - start_time).total_seconds() / 3600) + 1):
hour = (start_time + timezone.timedelta(hours=hour_offset))
if hour not in session_chart_data:
session_chart_data[hour] = 0 if hour <= tz_now else None
else:
session_chart_tooltip_format = "MMM d"
session_chart_granularity = "daily"
session_chart_data = {
k["date"]: k["count"]
for k in sessions.annotate(date=TruncDate("start_time"))
.values("date")
.annotate(count=models.Count("uuid"))
.order_by("date")
}
for day_offset in range((end_time - start_time).days + 1):
day = (start_time + timezone.timedelta(days=day_offset)).date()
if day not in session_chart_data:
session_chart_data[day] = 0 if day <= tz_now.date() else None
session_chart_data = {
k["date"]: k["count"]
for k in sessions.annotate(date=TruncDate("start_time"))
.values("date")
.annotate(count=models.Count("uuid"))
.order_by("date")
}
for day_offset in range((end_time - start_time).days + 1):
day = (start_time + timezone.timedelta(days=day_offset)).date()
if day not in session_chart_data:
session_chart_data[day] = 0
return {
"currently_online": currently_online,
@@ -269,8 +249,6 @@ class Service(models.Model):
)
]
),
"session_chart_tooltip_format": session_chart_tooltip_format,
"session_chart_granularity": session_chart_granularity,
"online": True,
}

View File

@@ -51,7 +51,7 @@
</div>
<hr class="sep h-4">
<div style="bottom: -1px;">
{% include 'dashboard/includes/time_chart.html' with data=stats.session_chart_data sparkline=True height=100 name=object.uuid tooltip_format=stats.session_chart_tooltip_format granularity=stats.session_chart_granularity %}
{% include 'dashboard/includes/time_chart.html' with data=stats.session_chart_data sparkline=True height=100 name=object.uuid %}
</div>
{% endwith %}
</a>

View File

@@ -6,9 +6,6 @@
},
tooltip: {
shared: false,
x: {
format: '{{tooltip_format|default:"MMM d"}}',
},
},
colors: ["#805AD5"],
chart: {
@@ -37,14 +34,6 @@
stops: [0, 75, 100]
},
},
{% if granularity == "daily" and click_zoom %}
events: {
markerClick: function(event, chartContext, { seriesIndex, dataPointIndex, w: {config}}) {
const day = config.series[seriesIndex].data[dataPointIndex].x
window.location.href = `?startDate=${day}&endDate=${day}`
},
},
{% endif %}
},
grid: {
padding: {
@@ -74,9 +63,6 @@
},
xaxis: {
type: "datetime",
labels: {
datetimeUTC: false
},
},
stroke: {
width: 1.5,

View File

@@ -94,7 +94,7 @@
{% endwith %}
</div>
<div class="card overflow-visible ~neutral !low py-0 mb-6">
{% include 'dashboard/includes/time_chart.html' with data=stats.session_chart_data tooltip_format=stats.session_chart_tooltip_format granularity=stats.session_chart_granularity click_zoom=True %}
{% include 'dashboard/includes/time_chart.html' with data=stats.session_chart_data %}
</div>
{% endif %}
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">

View File

@@ -25,7 +25,7 @@ from .mixins import DateRangeMixin
class DashboardView(LoginRequiredMixin, DateRangeMixin, ListView):
model = Service
template_name = "dashboard/pages/dashboard.html"
paginate_by = settings.DASHBOARD_PAGE_SIZE
paginate_by = 5
def get_queryset(self):
return Service.objects.filter(

View File

@@ -18,7 +18,7 @@ import urllib.parse as urlparse
from django.contrib.messages import constants as messages
# Increment on new releases
VERSION = "v0.9.1"
VERSION = "v0.8.2"
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -347,6 +347,3 @@ AGGRESSIVE_HASH_SALTING = os.getenv("AGGRESSIVE_HASH_SALTING", "False") == "True
# What location url should be linked to in the frontend?
LOCATION_URL = os.getenv("LOCATION_URL", "https://www.openstreetmap.org/?mlat=$LATITUDE&mlon=$LONGITUDE")
# How many services should be displayed on dashboard page?
DASHBOARD_PAGE_SIZE = int(os.getenv("DASHBOARD_PAGE_SIZE", "5"))