Show tempmon readings when viewing client or probe
also make the probes list more helpful when viewing client
This commit is contained in:
parent
7650064b64
commit
29e023096b
|
@ -24,6 +24,23 @@ div.form-wrapper ul.context-menu li {
|
|||
}
|
||||
|
||||
|
||||
/******************************
|
||||
* "object helper" panel
|
||||
******************************/
|
||||
|
||||
.object-helper {
|
||||
border: 1px solid black;
|
||||
float: right;
|
||||
margin-top: 1em;
|
||||
padding: 1em;
|
||||
width: 20em;
|
||||
}
|
||||
|
||||
.object-helper-content {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
|
||||
/******************************
|
||||
* Forms
|
||||
******************************/
|
||||
|
|
|
@ -40,18 +40,6 @@
|
|||
display: inline;
|
||||
}
|
||||
|
||||
.batch-helper {
|
||||
border: 1px solid black;
|
||||
float: right;
|
||||
margin-top: 1em;
|
||||
padding: 1em;
|
||||
width: 20em;
|
||||
}
|
||||
|
||||
.batch-helper-content {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
</style>
|
||||
</%def>
|
||||
|
||||
|
@ -92,9 +80,9 @@
|
|||
</ul>
|
||||
|
||||
% if status_breakdown is not Undefined:
|
||||
<div class="batch-helper">
|
||||
<div class="object-helper">
|
||||
<h3>Row Status Breakdown</h3>
|
||||
<div class="batch-helper-content">
|
||||
<div class="object-helper-content">
|
||||
% if status_breakdown:
|
||||
<div class="grid full">
|
||||
<table>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## -*- coding: utf-8; -*-
|
||||
<%inherit file="/master/view.mako" />
|
||||
|
||||
<%def name="head_tags()">
|
||||
|
@ -13,10 +13,23 @@
|
|||
</script>
|
||||
</%def>
|
||||
|
||||
${parent.body()}
|
||||
<ul id="context-menu">
|
||||
${self.context_menu_items()}
|
||||
</ul>
|
||||
|
||||
% if instance.enabled and master.restartable_client(instance) and request.has_perm('tempmon.clients.restart'):
|
||||
<div class="buttons">
|
||||
<button type="button" id="restart-client">Restart this Client</button>
|
||||
% if instance.enabled and master.restartable_client(instance) and request.has_perm('{}.restart'.format(route_prefix)):
|
||||
<div class="object-helper">
|
||||
<h3>Client Tools</h3>
|
||||
<div class="object-helper-content">
|
||||
<button type="button" id="restart-client">Restart tempmon-client daemon</button>
|
||||
</div>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
<div class="form-wrapper">
|
||||
${form.render()|n}
|
||||
</div><!-- form-wrapper -->
|
||||
|
||||
% if master.has_rows:
|
||||
${rows_grid|n}
|
||||
% endif
|
||||
|
|
|
@ -35,6 +35,7 @@ from rattail_tempmon.db import model as tempmon
|
|||
import colander
|
||||
from webhelpers2.html import HTML, tags
|
||||
|
||||
from tailbone import grids
|
||||
from tailbone.views.tempmon import MasterView
|
||||
|
||||
|
||||
|
@ -48,6 +49,9 @@ class TempmonClientView(MasterView):
|
|||
route_prefix = 'tempmon.clients'
|
||||
url_prefix = '/tempmon/clients'
|
||||
|
||||
has_rows = True
|
||||
model_row_class = tempmon.Reading
|
||||
|
||||
grid_columns = [
|
||||
'config_key',
|
||||
'hostname',
|
||||
|
@ -71,6 +75,12 @@ class TempmonClientView(MasterView):
|
|||
'archived',
|
||||
]
|
||||
|
||||
row_grid_columns = [
|
||||
'probe',
|
||||
'taken',
|
||||
'degrees_f',
|
||||
]
|
||||
|
||||
def configure_grid(self, g):
|
||||
super(TempmonClientView, self).configure_grid(g)
|
||||
|
||||
|
@ -106,15 +116,21 @@ class TempmonClientView(MasterView):
|
|||
f.set_enum('disk_type', self.enum.TEMPMON_DISK_TYPE)
|
||||
f.widgets['disk_type'].values.insert(0, ('', "(unknown)"))
|
||||
|
||||
# delay
|
||||
f.set_helptext('delay', tempmon.Client.delay.__doc__)
|
||||
|
||||
# probes
|
||||
f.set_renderer('probes', self.render_probes)
|
||||
if self.viewing:
|
||||
f.set_renderer('probes', self.render_probes)
|
||||
else:
|
||||
f.remove_field('probes')
|
||||
|
||||
# notes
|
||||
f.set_type('notes', 'text')
|
||||
|
||||
# online
|
||||
if self.creating or self.editing:
|
||||
f.remove_fields('probes',
|
||||
'online')
|
||||
f.remove_field('online')
|
||||
|
||||
def unique_config_key(self, node, value):
|
||||
query = self.Session.query(tempmon.Client)\
|
||||
|
@ -126,15 +142,43 @@ class TempmonClientView(MasterView):
|
|||
raise colander.Invalid(node, "Config key must be unique")
|
||||
|
||||
def render_probes(self, client, field):
|
||||
probes = client.probes
|
||||
if not probes:
|
||||
if not client.probes:
|
||||
return ""
|
||||
items = []
|
||||
for probe in probes:
|
||||
text = six.text_type(probe)
|
||||
url = self.request.route_url('tempmon.probes.view', uuid=probe.uuid)
|
||||
items.append(HTML.tag('li', c=[tags.link_to(text, url)]))
|
||||
return HTML.tag('ul', c=items)
|
||||
|
||||
route_prefix = self.get_route_prefix()
|
||||
view_url = lambda p, i: self.request.route_url('tempmon.probes.view', uuid=p.uuid)
|
||||
actions = [
|
||||
grids.GridAction('view', icon='zoomin', url=view_url),
|
||||
]
|
||||
if self.request.has_perm('tempmon.probes.edit'):
|
||||
url = lambda p, i: self.request.route_url('tempmon.probes.edit', uuid=p.uuid)
|
||||
actions.append(grids.GridAction('edit', icon='pencil', url=url))
|
||||
|
||||
g = grids.Grid(
|
||||
key='{}.probes'.format(route_prefix),
|
||||
data=client.probes,
|
||||
columns=[
|
||||
'description',
|
||||
'critical_temp_min',
|
||||
'good_temp_min',
|
||||
'good_temp_max',
|
||||
'critical_temp_max',
|
||||
'status',
|
||||
'enabled',
|
||||
],
|
||||
labels={
|
||||
'critical_temp_min': "Crit. Min",
|
||||
'good_temp_min': "Good Min",
|
||||
'good_temp_max': "Good Max",
|
||||
'critical_temp_max': "Crit. Max",
|
||||
},
|
||||
url=lambda p: self.request.route_url('tempmon.probes.view', uuid=p.uuid),
|
||||
linked_columns=['description'],
|
||||
main_actions=actions,
|
||||
)
|
||||
g.set_enum('status', self.enum.TEMPMON_PROBE_STATUS)
|
||||
g.set_type('enabled', 'boolean')
|
||||
return HTML.literal(g.render_grid())
|
||||
|
||||
def delete_instance(self, client):
|
||||
# bulk-delete all readings first
|
||||
|
@ -149,6 +193,24 @@ class TempmonClientView(MasterView):
|
|||
self.Session.delete(client)
|
||||
self.Session.flush()
|
||||
|
||||
def get_row_data(self, client):
|
||||
query = self.Session.query(tempmon.Reading)\
|
||||
.join(tempmon.Probe)\
|
||||
.filter(tempmon.Reading.client == client)
|
||||
return query
|
||||
|
||||
def get_parent(self, reading):
|
||||
return reading.client
|
||||
|
||||
def configure_row_grid(self, g):
|
||||
super(TempmonClientView, self).configure_row_grid(g)
|
||||
|
||||
# probe
|
||||
g.set_filter('probe', tempmon.Probe.description)
|
||||
g.set_sorter('probe', tempmon.Probe.description)
|
||||
|
||||
g.set_sort_defaults('taken', 'desc')
|
||||
|
||||
def restartable_client(self, client):
|
||||
return True
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import colander
|
|||
from deform import widget as dfwidget
|
||||
from webhelpers2.html import tags
|
||||
|
||||
from tailbone import grids
|
||||
from tailbone.views.tempmon import MasterView
|
||||
|
||||
|
||||
|
@ -47,6 +48,9 @@ class TempmonProbeView(MasterView):
|
|||
route_prefix = 'tempmon.probes'
|
||||
url_prefix = '/tempmon/probes'
|
||||
|
||||
has_rows = True
|
||||
model_row_class = tempmon.Reading
|
||||
|
||||
grid_columns = [
|
||||
'client',
|
||||
'config_key',
|
||||
|
@ -74,6 +78,11 @@ class TempmonProbeView(MasterView):
|
|||
'status',
|
||||
]
|
||||
|
||||
row_grid_columns = [
|
||||
'taken',
|
||||
'degrees_f',
|
||||
]
|
||||
|
||||
def configure_grid(self, g):
|
||||
super(TempmonProbeView, self).configure_grid(g)
|
||||
|
||||
|
@ -103,8 +112,10 @@ class TempmonProbeView(MasterView):
|
|||
f.set_label('client', "Tempmon Client")
|
||||
if self.creating or self.editing:
|
||||
f.replace('client', 'client_uuid')
|
||||
clients = self.Session.query(tempmon.Client)\
|
||||
.order_by(tempmon.Client.config_key)
|
||||
clients = self.Session.query(tempmon.Client)
|
||||
if self.creating:
|
||||
clients = clients.filter(tempmon.Client.archived == False)
|
||||
clients = clients.order_by(tempmon.Client.config_key)
|
||||
client_values = [(client.uuid, "{} ({})".format(client.config_key, client.hostname))
|
||||
for client in clients]
|
||||
f.set_widget('client_uuid', dfwidget.SelectWidget(values=client_values))
|
||||
|
@ -151,6 +162,23 @@ class TempmonProbeView(MasterView):
|
|||
self.Session.delete(probe)
|
||||
self.Session.flush()
|
||||
|
||||
def get_row_data(self, probe):
|
||||
query = self.Session.query(tempmon.Reading)\
|
||||
.filter(tempmon.Reading.probe == probe)
|
||||
return query
|
||||
|
||||
def get_parent(self, reading):
|
||||
return reading.client
|
||||
|
||||
def configure_row_grid(self, g):
|
||||
super(TempmonProbeView, self).configure_row_grid(g)
|
||||
|
||||
# # probe
|
||||
# g.set_filter('probe', tempmon.Probe.description)
|
||||
# g.set_sorter('probe', tempmon.Probe.description)
|
||||
|
||||
g.set_sort_defaults('taken', 'desc')
|
||||
|
||||
|
||||
def includeme(config):
|
||||
TempmonProbeView.defaults(config)
|
||||
|
|
Loading…
Reference in a new issue