forked from GithubBackups/healthchecks
Show overall project status in the top navigation menu and in the "Select Project" page. cc: #183
This commit is contained in:
parent
886643db84
commit
62310a5181
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -111,3 +111,7 @@ pre {
|
||||
font-size: small;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.badge-down {
|
||||
background-color: #d9534f;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -116,6 +116,7 @@
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li class="dropdown">
|
||||
<a id="nav-email" href="#" class="dropdown-toggle" data-toggle="dropdown" role="button">
|
||||
|
||||
{% if check %}
|
||||
{{ check.project }}
|
||||
{% elif request.profile.current_project %}
|
||||
@ -123,15 +124,23 @@
|
||||
{% else %}
|
||||
{{ request.user.email }}
|
||||
{% endif %}
|
||||
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
{% for project in request.profile.projects.all %}
|
||||
{% for project in request.profile.annotated_projects %}
|
||||
<li class="dropdown-header">{{ project }}</li>
|
||||
<li>
|
||||
<a href="{% url 'hc-checks' project.code %}">Checks</a>
|
||||
<a href="{% url 'hc-checks' project.code %}">
|
||||
Checks
|
||||
{% if project.n_down %}
|
||||
<span class="badge badge-down pull-right">
|
||||
{{ project.n_down }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% if project.owner == request.user %}
|
||||
{% if project.owner_id == request.user.id %}
|
||||
<li>
|
||||
<a href="{% url 'hc-project-settings' project.code %}">Project Settings</a>
|
||||
</li>
|
||||
|
@ -19,15 +19,18 @@
|
||||
</h1>
|
||||
|
||||
<div id="project-selector" class="row">
|
||||
{% for project in projects%}
|
||||
{% for project in projects %}
|
||||
<a href="{% url 'hc-checks' project.code %}">
|
||||
<div class="col-sm-6 col-md-4">
|
||||
<div class="panel project {% if project == request.profile.current_project %}selected{% endif %}">
|
||||
{% if project == request.profile.current_project %}
|
||||
<div class="marker">Current Project</div>
|
||||
{% if project.n_down %}
|
||||
<div class="status icon-down"></div>
|
||||
{% else %}
|
||||
<div class="status icon-up"></div>
|
||||
{% endif %}
|
||||
|
||||
<h4>{{ project }}</h4>
|
||||
|
||||
<div>
|
||||
{% with project.check_set.count as n %}
|
||||
{{ n }} check{{ n|pluralize }},
|
||||
@ -40,6 +43,7 @@
|
||||
<div class="text-muted">
|
||||
{{ project.owner.email }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
Loading…
x
Reference in New Issue
Block a user