0001-turn-home-page-into-a-list-of-services-status-26761.patch
hobo/static/css/style.css | ||
---|---|---|
154 | 154 |
div.buttons { |
155 | 155 |
margin: 1em 0; |
156 | 156 |
} |
157 | ||
158 |
div#services > div { |
|
159 |
box-sizing: border-box; |
|
160 |
background: white; |
|
161 |
border: 1px solid #ccc; |
|
162 |
border-width: 1px 1px 1px 10px; |
|
163 |
margin-bottom: 1rem; |
|
164 |
width: 49%; |
|
165 |
padding: 0 1ex; |
|
166 |
} |
|
167 | ||
168 |
div#services > div h3 { |
|
169 |
margin-top: 0.5rem; |
|
170 |
} |
|
171 | ||
172 |
div#services > div h3 a { |
|
173 |
font-size: 80%; |
|
174 |
font-weight: normal; |
|
175 |
} |
|
176 | ||
177 |
div#services > div:nth-child(2n+1) { |
|
178 |
float: left; |
|
179 |
} |
|
180 | ||
181 |
div#services > div:nth-child(2n) { |
|
182 |
float: right; |
|
183 |
} |
|
184 | ||
185 |
div#services > div.op-ok { |
|
186 |
border-color: #00b000; |
|
187 |
} |
|
188 | ||
189 |
div#services > div.op-nok { |
|
190 |
border-color: #b00000; |
|
191 |
} |
|
192 | ||
193 |
div#services p { |
|
194 |
margin-bottom: 0.5rem; |
|
195 |
} |
|
196 | ||
197 |
div#services span.op-ok::before { |
|
198 |
font-family: FontAwesome; |
|
199 |
content: "\f058"; /* check-circle */ |
|
200 |
display: inline-block; |
|
201 |
width: 1.5rem; |
|
202 |
color: #00b000; |
|
203 |
} |
|
204 | ||
205 |
div#services span.op-nok::before { |
|
206 |
font-family: FontAwesome; |
|
207 |
content: "\f057"; /* times-circle */ |
|
208 |
display: inline-block; |
|
209 |
width: 1.5rem; |
|
210 |
color: #b00000; |
|
211 |
} |
|
212 | ||
213 |
div#services span { |
|
214 |
margin-right: 1rem; |
|
215 |
} |
hobo/templates/hobo/home.html | ||
---|---|---|
2 | 2 |
{% load i18n %} |
3 | 3 | |
4 | 4 |
{% block appbar %} |
5 |
<h2>{% trans 'Welcome' %}</h2> |
|
5 |
<h2>{% trans 'System' %}</h2> |
|
6 |
<span class="actions"> |
|
7 |
<a class="extra-actions-menu-opener"></a> |
|
8 |
<ul class="extra-actions-menu"> |
|
9 |
<li><a href="{% url 'profile-home' %}">{% trans 'User Profile' %}</a></li> |
|
10 |
<li><a href="{% url 'theme-home' %}">{% trans 'Theme' %}</a></li> |
|
11 |
<li><a href="{% url 'emails-home' %}">{% trans 'Emails' %}</a></li> |
|
12 |
<li><a href="{% url 'environment-home' %}">{% trans 'Services' %}</a></li> |
|
13 |
<li><a href="{% url 'environment-variables' %}">{% trans 'Variables' %}</a></li> |
|
14 |
</ul> |
|
15 |
</span> |
|
6 | 16 |
{% endblock %} |
7 | 17 | |
8 | 18 |
{% block content %} |
9 | 19 | |
10 |
<ul class="apps"> |
|
11 |
<li class="icon-users"><a href="{% url 'profile-home' %}">{% trans 'User Profile' %}</a></li> |
|
12 |
<li class="icon-theme"><a href="{% url 'theme-home' %}">{% trans 'Theme' %}</a></li> |
|
13 |
<li class="icon-mail"><a href="{% url 'emails-home' %}">{% trans 'Emails' %}</a></li> |
|
14 |
<li class="icon-portal"><a href="{% url 'environment-home' %}">{% trans 'Sites' %}</a></li> |
|
15 |
<li class="icon-settings"><a href="{% url 'environment-variables' %}">{% trans 'Variables' %}</a></li> |
|
16 |
</ul> |
|
20 |
{% if services %} |
|
21 |
<div id="services"> |
|
22 |
{% for service in services %} |
|
23 |
<div class="service-{{ service.Extra.service_id }}" |
|
24 |
data-service-slug="{{ service.slug }}"> |
|
25 |
<h3>{{ service.title }} <a href="{{ service.base_url }}">{{ service.base_url }}</a></h3> |
|
26 |
<p> |
|
27 |
<span class="checking">{% trans "checking..." %}</span> |
|
28 |
<span style="display: none" class="dns">{% trans "DNS" %}</span> |
|
29 |
<span style="display: none" class="certificate">{% trans "Certificate" %}</span> |
|
30 |
<span style="display: none" class="web">{% trans "Web" %}</span> |
|
31 |
</p> |
|
32 |
</div> |
|
33 |
{% endfor %} |
|
34 |
</div> |
|
35 |
{% else %} |
|
36 |
<div class="big-msg-info"> |
|
37 |
{% blocktrans %} |
|
38 |
This deployment doesn't have any service deployed yet. Click on the |
|
39 |
"Services" menu entry in the top right of the page to add a first one. |
|
40 |
{% endblocktrans %} |
|
41 |
</div> |
|
42 |
{% endif %} |
|
43 | ||
44 |
<script> |
|
45 |
$(function() { |
|
46 |
$.ajax({ |
|
47 |
url: '/api/health/', |
|
48 |
success: function(response, status) { |
|
49 |
$('div[data-service-slug]').each(function(idx, service_block) { |
|
50 |
var $service_block = $(service_block); |
|
51 |
var service_slug = $service_block.data('service-slug'); |
|
52 |
var service = response.data[service_slug]; |
|
53 |
var ok = true; |
|
54 |
if (service.is_resolvable) { |
|
55 |
$service_block.find('.dns').addClass('op-ok'); |
|
56 |
} else { |
|
57 |
$service_block.find('.dns').addClass('op-nok'); |
|
58 |
ok = false; |
|
59 |
} |
|
60 |
if (service.has_valid_certificate) { |
|
61 |
$service_block.find('.certificate').addClass('op-ok'); |
|
62 |
} else { |
|
63 |
$service_block.find('.certificate').addClass('op-nok'); |
|
64 |
ok = false; |
|
65 |
} |
|
66 |
if (service.is_running) { |
|
67 |
$service_block.find('.web').addClass('op-ok'); |
|
68 |
} else { |
|
69 |
$service_block.find('.web').addClass('op-nok'); |
|
70 |
ok = false; |
|
71 |
} |
|
72 |
var $service_p = $service_block.find('span.checking') |
|
73 |
$service_block.find('span').show(); |
|
74 |
$service_p.hide(); |
|
75 |
if (ok) { |
|
76 |
$service_block.addClass('op-ok'); |
|
77 |
} else { |
|
78 |
$service_block.addClass('op-nok'); |
|
79 |
} |
|
80 |
}); |
|
81 |
} |
|
82 |
}); |
|
83 |
}); |
|
84 |
</script> |
|
17 | 85 | |
18 | 86 |
{% endblock %} |
hobo/views.py | ||
---|---|---|
15 | 15 |
from django.utils.encoding import force_text |
16 | 16 | |
17 | 17 |
from .environment.models import Authentic |
18 |
from .environment.utils import Zone, get_operational_services
|
|
18 |
from .environment.utils import Zone, get_installed_services
|
|
19 | 19 |
from .forms import HoboForm, HoboUpdateForm, get_tenant_model |
20 | 20 | |
21 | 21 |
def is_superuser(u): |
... | ... | |
30 | 30 |
class Home(TemplateView): |
31 | 31 |
template_name = 'hobo/home.html' |
32 | 32 | |
33 |
def get_context_data(self, **kwargs): |
|
34 |
context = super(Home, self).get_context_data(**kwargs) |
|
35 |
context['services'] = [x for x in get_installed_services() if not x.secondary] |
|
36 |
return context |
|
37 | ||
33 | 38 |
home = admin_required(Home.as_view()) |
34 | 39 | |
35 | 40 |
class ManagerHome(edit.CreateView): |
36 |
- |