diff --git a/hc/accounts/models.py b/hc/accounts/models.py index dc2f9604..e38501b4 100644 --- a/hc/accounts/models.py +++ b/hc/accounts/models.py @@ -8,6 +8,7 @@ from django.contrib.auth.hashers import check_password, make_password from django.contrib.auth.models import User from django.core.signing import TimestampSigner from django.db import models +from django.db.models import Count, Q from django.urls import reverse from django.utils import timezone from hc.lib import emails @@ -113,11 +114,21 @@ class Profile(models.Model): def projects(self): """ Return a queryset of all projects we have access to. """ - is_owner = models.Q(owner=self.user) - is_member = models.Q(member__user=self.user) + is_owner = Q(owner=self.user) + is_member = Q(member__user=self.user) q = Project.objects.filter(is_owner | is_member) return q.distinct().order_by("name") + def annotated_projects(self): + """ Return all projects, annotated with 'n_down'. """ + + is_owner = Q(owner=self.user) + is_member = Q(member__user=self.user) + q = Project.objects.filter(is_owner | is_member) + n_down = Count("check", filter=Q(check__status="down")) + q = q.annotate(n_down=n_down) + return q.distinct().order_by("name") + def checks_from_all_projects(self): """ Return a queryset of checks from projects we have access to. """ @@ -236,8 +247,8 @@ class Project(models.Model): def set_next_nag_date(self): """ Set next_nag_date on profiles of all members of this project. """ - is_owner = models.Q(user=self.owner) - is_member = models.Q(user__memberships__project=self) + is_owner = Q(user=self.owner) + is_member = Q(user__memberships__project=self) q = Profile.objects.filter(is_owner | is_member) q = q.exclude(nag_period=NO_NAG) # Exclude profiles with next_nag_date already set diff --git a/hc/accounts/views.py b/hc/accounts/views.py index afd89b78..8c6ade44 100644 --- a/hc/accounts/views.py +++ b/hc/accounts/views.py @@ -307,8 +307,8 @@ def project(request, code): project.name = form.cleaned_data["name"] project.save() - if request.project.id == project.id: - request.project = project + if request.profile.current_project == project: + request.profile.current_project.name = project.name ctx["project_name_updated"] = True ctx["project_name_status"] = "success" diff --git a/hc/front/views.py b/hc/front/views.py index 9a5f136b..871255b7 100644 --- a/hc/front/views.py +++ b/hc/front/views.py @@ -195,7 +195,7 @@ def switch_channel(request, code, channel_code): def index(request): if request.user.is_authenticated: - projects = list(request.profile.projects()) + projects = list(request.profile.annotated_projects()) if len(projects) == 1: return redirect("hc-checks", projects[0].code) diff --git a/static/css/base.css b/static/css/base.css index 1e22f588..5b5c2291 100644 --- a/static/css/base.css +++ b/static/css/base.css @@ -111,3 +111,7 @@ pre { font-size: small; padding: 2px 0; } + +.badge-down { + background-color: #d9534f; +} diff --git a/static/css/projects.css b/static/css/projects.css index 711f2270..29a3ea68 100644 --- a/static/css/projects.css +++ b/static/css/projects.css @@ -12,23 +12,19 @@ #project-selector .project { border-color: #ddd; - padding: 24px; + padding: 24px 24px 24px 64px; position: relative; } +#project-selector .project h4 { + margin-top: 0; +} + #project-selector .project.selected { border-color: #0091EA; } -#project-selector .project.selected .marker { - display: block; +#project-selector .project .status { position: absolute; - top: 0; - font-size: 10px; - padding: 2px 8px; - border-bottom-left-radius: 3px; - border-bottom-right-radius: 3px; - color: #fff; - background: #0091EA; - text-transform: uppercase; -} + left: 24px; +} \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index ef9dc09a..1576710b 100644 --- a/templates/base.html +++ b/templates/base.html @@ -116,6 +116,7 @@