diff --git a/hc/accounts/admin.py b/hc/accounts/admin.py index 73e354d9..2196fca8 100644 --- a/hc/accounts/admin.py +++ b/hc/accounts/admin.py @@ -9,6 +9,27 @@ from django.utils.safestring import mark_safe from hc.accounts.models import Profile, Project +@mark_safe +def _format_usage(num_checks, num_channels): + result = "" + + if num_checks == 0: + result += "0 checks, " + elif num_checks == 1: + result += "1 check, " + else: + result += f"{num_checks} checks, " + + if num_channels == 0: + result += "0 channels" + elif num_channels == 1: + result += "1 channel" + else: + result += f"{num_channels} channels" + + return result + + class Fieldset: name = None fields = [] @@ -56,9 +77,9 @@ class ProfileAdmin(admin.ModelAdmin): list_display = ( "id", "email", - "engagement", + "usage", "date_joined", - "last_login", + "last_active_date", "projects", "invited", "sms", @@ -66,7 +87,7 @@ class ProfileAdmin(admin.ModelAdmin): ) list_filter = ( "user__date_joined", - "user__last_login", + "last_active_date", "reports_allowed", "check_limit", ) @@ -82,25 +103,8 @@ class ProfileAdmin(admin.ModelAdmin): qs = qs.annotate(plan=F("user__subscription__plan_name")) return qs - @mark_safe - def engagement(self, obj): - result = "" - - if obj.num_checks == 0: - result += "0 checks, " - elif obj.num_checks == 1: - result += "1 check, " - else: - result += "%d checks, " % obj.num_checks - - if obj.num_channels == 0: - result += "0 channels" - elif obj.num_channels == 1: - result += "1 channel, " - else: - result += "%d channels, " % obj.num_channels - - return result + def usage(self, obj): + return _format_usage(obj.num_checks, obj.num_channels) @mark_safe def email(self, obj): @@ -110,9 +114,6 @@ class ProfileAdmin(admin.ModelAdmin): return s - def last_login(self, obj): - return obj.user.last_login - def date_joined(self, obj): return obj.user.date_joined @@ -131,7 +132,7 @@ class ProfileAdmin(admin.ModelAdmin): class ProjectAdmin(admin.ModelAdmin): readonly_fields = ("code", "owner") list_select_related = ("owner",) - list_display = ("id", "name_", "users", "engagement", "switch") + list_display = ("id", "name_", "users", "usage", "switch") search_fields = ["id", "name", "owner__email"] class Media: @@ -160,25 +161,8 @@ class ProjectAdmin(admin.ModelAdmin): def email(self, obj): return obj.owner.email - @mark_safe - def engagement(self, obj): - result = "" - - if obj.num_checks == 0: - result += "0 checks, " - elif obj.num_checks == 1: - result += "1 check, " - else: - result += "%d checks, " % obj.num_checks - - if obj.num_channels == 0: - result += "0 channels" - elif obj.num_channels == 1: - result += "1 channel, " - else: - result += "%d channels, " % obj.num_channels - - return result + def usage(self, obj): + return _format_usage(obj.num_checks, obj.num_channels) @mark_safe def switch(self, obj): @@ -191,7 +175,7 @@ class HcUserAdmin(UserAdmin): list_display = ( "id", "email", - "engagement", + "usage", "date_joined", "last_login", "is_staff", @@ -210,24 +194,8 @@ class HcUserAdmin(UserAdmin): return qs @mark_safe - def engagement(self, user): - result = "" - - if user.num_checks == 0: - result += "0 checks, " - elif user.num_checks == 1: - result += "1 check, " - else: - result += "%d checks, " % user.num_checks - - if user.num_channels == 0: - result += "0 channels" - elif user.num_channels == 1: - result += "1 channel, " - else: - result += "%d channels, " % user.num_channels - - return result + def usage(self, user): + return _format_usage(user.num_checks, user.num_channels) def send_report(self, request, qs): for user in qs: diff --git a/hc/api/admin.py b/hc/api/admin.py index 64628281..79add96b 100644 --- a/hc/api/admin.py +++ b/hc/api/admin.py @@ -2,6 +2,8 @@ from django.contrib import admin from django.core.paginator import Paginator from django.db import connection from django.db.models import Count, F +from django.urls import reverse +from django.utils.html import escape from django.utils.safestring import mark_safe from hc.api.models import Channel, Check, Flip, Notification, Ping from hc.lib.date import format_duration @@ -17,7 +19,7 @@ class ChecksAdmin(admin.ModelAdmin): list_display = ( "id", "name_tags", - "email", + "project_", "created", "n_pings", "timeout_schedule", @@ -32,16 +34,26 @@ class ChecksAdmin(admin.ModelAdmin): def get_queryset(self, request): qs = super().get_queryset(request) qs = qs.annotate(email=F("project__owner__email")) + qs = qs.annotate(project_name=F("project__name")) return qs - def email(self, obj): - return obj.email + @mark_safe + def project_(self, obj): + url = reverse("hc-checks", args=[obj.project.code]) + name = escape(obj.project_name or "Default") + email = escape(obj.email) + return f'{name} • {email}' + @mark_safe def name_tags(self, obj): - if not obj.tags: - return obj.name + url = reverse("hc-details", args=[obj.code]) + name = escape(obj.name or "unnamed") + + s = f'{name}' + for tag in obj.tags_list(): + s += " %s" % escape(tag) - return "%s [%s]" % (obj.name, obj.tags) + return s def timeout_schedule(self, obj): if obj.kind == "simple": @@ -166,7 +178,7 @@ class ChannelsAdmin(admin.ModelAdmin): list_display = ( "id", "name", - "email", + "project_", "formatted_kind", "value", "num_notifications", @@ -174,15 +186,20 @@ class ChannelsAdmin(admin.ModelAdmin): list_filter = ("kind",) raw_id_fields = ("project", "checks") + @mark_safe + def project_(self, obj): + url = reverse("hc-checks", args=[obj.project.code]) + name = escape(obj.project_name or "Default") + email = escape(obj.email) + return f"{name} • {email}" + def get_queryset(self, request): qs = super().get_queryset(request) qs = qs.annotate(Count("notification", distinct=True)) + qs = qs.annotate(project_name=F("project__name")) qs = qs.annotate(email=F("project__owner__email")) return qs - def email(self, obj): - return obj.email - @mark_safe def formatted_kind(self, obj): if obj.kind == "email" and not obj.email_verified: @@ -213,6 +230,7 @@ class NotificationsAdmin(admin.ModelAdmin): "error", ) list_filter = ("created", "check_status", "channel__kind") + raw_id_fields = ("channel",) def channel_kind(self, obj): return obj.channel.kind diff --git a/static/css/admin/checks.css b/static/css/admin/checks.css index 5fed941b..51fa0688 100644 --- a/static/css/admin/checks.css +++ b/static/css/admin/checks.css @@ -1,4 +1,11 @@ .field-code { font-family: monospace; font-size: 80%; +} + +.field-name_tags span { + color: #555; + background: #EEE; + padding: 1px 4px; + border-radius: 2px; } \ No newline at end of file