Switch the interface to Semantic-UI.

This commit is contained in:
Daniele Sluijters
2014-03-13 11:49:24 +01:00
parent ce4c7a26cd
commit bcb45c24a4
17 changed files with 327 additions and 408 deletions

View File

@@ -1,104 +1,57 @@
body { body {
padding-top: 60px; margin: 0;
font-family: "Open Sans", sans-serif;
} }
th.headerSortUp {
position: relative a {
color: #564F8A;
text-decoration: none;
} }
th.headerSortDown {
position: relative h1.ui.header.no-margin-bottom {
margin-bottom: 0;
} }
th.header {
position: relative .tablesorter-header-inner {
float: left;
} }
th.header:after {
content: "\f0dc"; th.tablesorter-headerAsc::after {
font-family: FontAwesome; content: '\25b4' !important;
font-style: normal;
font-weight: normal;
text-decoration: inherit;
color: #000;
font-size: 18px;
padding-right: 0.5em;
float: right; float: right;
} }
th.headerSortUp:after {
content: "\f0de"; th.tablesorter-headerDesc::after {
font-family: FontAwesome; content: '\25be' !important;
font-style: normal;
font-weight: normal;
text-decoration: inherit;
color: #000;
font-size: 18px;
padding-right: 0.5em;
float: right; float: right;
} }
th.headerSortDown:after {
content: "\f0dd"; .ui.grid.padding-bottom {
font-family: FontAwesome; padding-bottom: 40px !important;
font-style: normal;
font-weight: normal;
text-decoration: inherit;
color: #000;
font-size: 18px;
padding-right: 0.5em;
float:right;
} }
.stat {
margin-bottom: 40px; .status {
} width: 47%;
.navbar .brand:hover {
color: #fff;
}
.table tbody tr.error>td {
background-color: #f2dede;
}
h1.error {
color: rgb(223, 46, 27);
}
h1.success {
color: #18BC9C;
}
h1.noop {
color:#aaa;
}
tr.event {
cursor: pointer;
}
td.message {
padding: 0;
border: 0;
background-color: #FFFFE9;
}
div[id^='message-event'] {
display: none;
padding: 4px 15px 4px 15px;
}
.label-count {
width:25px;
text-align: center; text-align: center;
display: block;
} }
.label-time { .count {
width:73px; width: 21%;
text-align: center; text-align: center;
display: block;
} }
.label-status {
width:100px; .no-margin-top {
text-align:center; margin-top: -35px !important;
} }
.label-nothing {
background-color:#ddd; .absolute {
color:#ddd; position: fixed;
bottom: 0;
width: 100%;
background: #E8E8E8;
} }
.label.label-failed {
background-color: rgb(231, 76, 60); .absolute div {
} padding: 1em;
.label.label-changed {
background-color: rgb(24, 188, 156);
}
.label.label-unreported {
background-color: rgb(231, 76, 60);
background-color: rgb(129, 145, 146);
}
.btn-lastreport {
width:100px;
} }

View File

@@ -0,0 +1,9 @@
/*
A simple, lightweight jQuery plugin for creating sortable tables.
https://github.com/kylefox/jquery-tablesort
Version 0.0.2
*/
$(function(){var a=window.jQuery;a.tablesort=function(d,c){var e=this;this.$table=d;this.$thead=this.$table.find("thead");this.settings=a.extend({},a.tablesort.defaults,c);this.$table.find("th").bind("click.tablesort",function(){e.sort(a(this))});this.direction=this.$th=this.index=null};a.tablesort.prototype={sort:function(d,c){var e=new Date,b=this,g=this.$table,n=0<this.$thead.length?g.find("tbody tr"):g.find("tr").has("td"),m=g.find("tr td:nth-of-type("+(d.index()+1)+")"),h=d.data().sortBy,k=[],
l=m.map(function(c,e){return h?"function"===typeof h?h(a(d),a(e),b):h:null!=a(this).data().sortValue?a(this).data().sortValue:a(this).text()});if(0!==l.length){b.$table.find("th").removeClass(b.settings.asc+" "+b.settings.desc);this.direction="asc"!==c&&"desc"!==c?"asc"===this.direction?"desc":"asc":c;c="asc"==this.direction?1:-1;b.$table.trigger("tablesort:start",[b]);b.log("Sorting by "+this.index+" "+this.direction);for(var f=0,p=l.length;f<p;f++)k.push({index:f,cell:m[f],row:n[f],value:l[f]});
k.sort(function(a,b){return a.value>b.value?1*c:a.value<b.value?-1*c:0});a.each(k,function(a,b){g.append(b.row)});d.addClass(b.settings[b.direction]);b.log("Sort finished in "+((new Date).getTime()-e.getTime())+"ms");b.$table.trigger("tablesort:complete",[b])}},log:function(d){(a.tablesort.DEBUG||this.settings.debug)&&console&&console.log&&console.log("[tablesort] "+d)},destroy:function(){this.$table.find("th").unbind("click.tablesort");this.$table.data("tablesort",null);return null}};a.tablesort.DEBUG=
!1;a.tablesort.defaults={debug:a.tablesort.DEBUG,asc:"sorted ascending",desc:"sorted descending"};a.fn.tablesort=function(d){var c,e;return this.each(function(){c=a(this);(e=c.data("tablesort"))&&e.destroy();c.data("tablesort",new a.tablesort(c,d))})}});

View File

@@ -1,11 +1,5 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block row_fluid %} {% block content %}
<div class="container" style="margin-bottom:55px;"> <h1>Bad Request</h1>
<div class="row">
<div class="span12">
<h2>Bad Request</h2>
<p>The request sent to PuppetDB was invalid. This is usually caused by using an unsupported operator.</p> <p>The request sent to PuppetDB was invalid. This is usually caused by using an unsupported operator.</p>
</div>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,11 +1,5 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block row_fluid %} {% block content %}
<div class="container" style="margin-bottom:55px;"> <h1>Permission Denied</h1>
<div class="row">
<div class="span12">
<h2>Permission Denied</h2>
<p>What you were looking for has been disabled by the administrator.</p> <p>What you were looking for has been disabled by the administrator.</p>
</div>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,11 +1,5 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block row_fluid %} {% block content%}
<div class="container" style="margin-bottom:55px;"> <h1>Not Found</h1>
<div class="row">
<div class="span12">
<h2>Not Found</h2>
<p>What you were looking for could not be found in PuppetDB.</p> <p>What you were looking for could not be found in PuppetDB.</p>
</div>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,8 +1,5 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block row_fluid %} {% block content %}
<div class="container" style="margin-bottom:55px;">
<div class="row">
<div class="span12">
<h2>Internal Server Error</h2> <h2>Internal Server Error</h2>
<p>This error usually occurs because: <p>This error usually occurs because:
<ul> <ul>
@@ -10,7 +7,4 @@
<Li>The query to be executed was malformed resulting in an incorrectly encoded request.</li> <Li>The query to be executed was malformed resulting in an incorrectly encoded request.</li>
</ul></p> </ul></p>
<p>Please have a look at the log output for further information.</p> <p>Please have a look at the log output for further information.</p>
</div>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,8 +1,8 @@
{% macro facts_table(facts, autofocus=False, condensed=False, show_node=False, show_value=True, link_facts=False, margin_top=20, margin_bottom=20) -%} {% macro facts_table(facts, autofocus=False, condensed=False, show_node=False, show_value=True, link_facts=False, margin_top=20, margin_bottom=20) -%}
<div class="filter" style="margin-bottom:{{margin_bottom}}px;margin-top:{{margin_top}}px;"> <div class="ui fluid icon input hide" style="margin-bottom:20px">
<input {% if autofocus %} autofocus="autofocus" {% endif %} style="width:100%" type="text" class="filter-table input-medium search-query" placeholder="Type here to filter"> <input {% if autofocus %} autofocus="autofocus" {% endif %} class="filter-table" placeholder="Type here to filter...">
</div> </div>
<table class="filter-table facts table table-striped {% if condensed %}table-condensed{% endif%}" style="table-layout:fixed"> <table class="filter-table facts ui basic table facts {% if condensed %}compact{% endif%}" style="table-layout: fixed;">
<thead> <thead>
<tr> <tr>
{% if show_node %} {% if show_node %}
@@ -96,10 +96,10 @@
{%- endmacro %} {%- endmacro %}
{% macro reports_table(reports, nodename, condensed=False, hash_truncate=False, show_conf_col=True, show_agent_col=True, show_host_col=True) -%} {% macro reports_table(reports, nodename, condensed=False, hash_truncate=False, show_conf_col=True, show_agent_col=True, show_host_col=True) -%}
<div class="alert alert-info"> <div class="ui info message">
Only showing the last ten reports. Only showing the last ten reports.
</div> </div>
<table class='table table-striped {% if condensed %}table-condensed{% endif %}'> <table class='ui table basic {% if condensed %}compact{% endif %}'>
<thead> <thead>
<tr> <tr>
<th>Start time</th> <th>Start time</th>
@@ -119,7 +119,7 @@
<tbody> <tbody>
{% for report in reports %} {% for report in reports %}
{% if hash_truncate %} {% if hash_truncate %}
{% set rep_hash = "%s&hellip;"|format(report.hash_[0:6])|safe %} {% set rep_hash = "%s&hellip;"|format(report.hash_[0:10])|safe %}
{% else %} {% else %}
{% set rep_hash = report.hash_ %} {% set rep_hash = report.hash_ %}
{% endif %} {% endif %}
@@ -139,7 +139,7 @@
<td>{{report.agent_version}}</td> <td>{{report.agent_version}}</td>
{% endif %} {% endif %}
{% if show_host_col %} {% if show_host_col %}
<td>{{nodename}}</td> <td><a href="{{url_for('node', node_name=report.node)}}">{{ report.node }}</a></td>
{% endif %} {% endif %}
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -2,8 +2,8 @@
{% import '_macros.html' as macros %} {% import '_macros.html' as macros %}
{% block content %} {% block content %}
<h1>{{name}}{% if value %}/{{value}}{% endif %} ({{facts|length}})</h1> <h1>{{name}}{% if value %}/{{value}}{% endif %} ({{facts|length}})</h1>
{{macros.facts_graph(facts, autofocus=True, show_node=True, margin_bottom=10)}} {#{{macros.facts_graph(facts, autofocus=True, show_node=True, margin_bottom=10)}}#
{{macros.facts_graph_value(facts, autofocus=True, show_node=True, margin_bottom=10)}} {{macros.facts_graph_value(facts, autofocus=True, show_node=True, margin_bottom=10)}}#}
{% if value %} {% if value %}
{{macros.facts_table(facts, autofocus=True, show_node=True, show_value=False, margin_bottom=10)}} {{macros.facts_table(facts, autofocus=True, show_node=True, show_value=False, margin_bottom=10)}}
{% else %} {% else %}

View File

@@ -1,11 +1,11 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block content %} {% block content %}
<div class="hide" style="margin-bottom:20px"> <div class="ui fluid icon input hide" style="margin-bottom:20px">
<input autofocus="autofocus" style="width:100%" type="text" class="filter-list input-medium search-query" placeholder="Type here to filter"> <input autofocus="autofocus" class="filter-list" placeholder="Type here to filter...">
</div> </div>
<div style="-moz-column-count:4; -webkit-column-count:4; column-count:4;"> <div style="-moz-column-count:4; -webkit-column-count:4; column-count:4;">
{%- for key,facts_list in facts_dict %} {%- for key,facts_list in facts_dict %}
<span class='label label-success'>{{key}}</span> <span class='ui label purple'>{{key}}</span>
<ul class="searchable"> <ul class="searchable">
{%- for fact in facts_list %} {%- for fact in facts_list %}
<li><a href="{{url_for('fact', fact=fact)}}">{{fact}}</a></li> <li><a href="{{url_for('fact', fact=fact)}}">{{fact}}</a></li>

View File

@@ -1,65 +1,61 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block row_fluid %} {% block content %}
<div class="container" style="margin-bottom:55px;"> <div class="ui vertical grid">
<div class="three column row">
<div class="row"> <div class="column">
<div class="span12">
<div class="span4 stat">
<a href="nodes?status=failed"> <a href="nodes?status=failed">
<h1 class="error">{{stats['failed']}} <h1 class="ui red header no-margin-bottom">
{{stats['failed']}}
<small>{% if stats['failed']== 1 %} node {% else %} nodes {% endif %}</small> <small>{% if stats['failed']== 1 %} node {% else %} nodes {% endif %}</small>
</h1> </h1>
</a> </a>
<span>with status failed</span> <span>with status failed</span>
</div> </div>
<div class="span4 stat"> <div class="column">
<a href="nodes?status=changed"> <a href="nodes?status=changed">
<h1 class="success">{{stats['changed']}} <h1 class="ui header green no-margin-bottom">
{{stats['changed']}}
<small>{% if stats['changed']== 1 %} node {% else %} nodes {% endif %}</small> <small>{% if stats['changed']== 1 %} node {% else %} nodes {% endif %}</small>
</h1> </h1>
</a> </a>
<span>with status changed</span> <span>with status changed</span>
</div> </div>
<div class="span4 stat"> <div class="column">
<a href="nodes?status=unreported"> <a href="nodes?status=unreported">
<h1 class="noop">{{ stats['unreported'] }} <h1 class="ui header black no-margin-bottom">
{{ stats['unreported'] }}
<small>{% if stats['unreported']== 1 %} node {% else %} nodes {% endif %}</small> <small>{% if stats['unreported']== 1 %} node {% else %} nodes {% endif %}</small>
</h1> </h1>
</a> </a>
<span> <span>unreported in the last {{ config.UNRESPONSIVE_HOURS }} hours</span>
unreported in the last {{ config.UNRESPONSIVE_HOURS }} hours
</span>
</div> </div>
</div> </div>
</div> <div class="three column row">
<div class="column">
<div class="row"> <h1 class="ui header purple no-margin-bottom">{{metrics['num_nodes']}}</h1>
<div class="span12">
<div class="span4 stat">
<h1>{{metrics['num_nodes']}}</h1>
<span>Population</span> <span>Population</span>
</div> </div>
<div class="span4 stat"> <div class="column">
<h1>{{metrics['num_resources']}}</h1> <h1 class="ui header purple no-margin-bottom">{{metrics['num_resources']}}</h1>
<span>Resources managed</span> <span>Resources managed</span>
</div> </div>
<div class="span4 stat"> <div class="column">
<h1>{{metrics['avg_resources_node']}}</h1> <h1 class="ui header purple no-margin-bottom">{{metrics['avg_resources_node']}}</h1>
<span>Avg. resources/node</span> <span>Avg. resources/node</span>
</div> </div>
</div> </div>
<div class="ui divider">
</div> </div>
<div class="one column row no-margin-top">
<div class="row"> <div class="column">
<div class="span12">
{% if nodes %} {% if nodes %}
<h2>Nodes status detail ({{nodes|length}})</h2> <h2>Nodes status detail ({{nodes|length}})</h2>
<table class='dashboard table table-striped table-condensed'> <table class='ui compact basic table dashboard'>
<thead> <thead>
<tr> <tr>
<th style="min-width:220px;">Status</th> <th class="five wide">Status</th>
<th style="width:600px;">Hostname</th> <th class="ten wide">Hostname</th>
<th style="width:120px;"></th> <th class="one wide"></th>
</tr> </tr>
</thead> </thead>
<tbody class="searchable"> <tbody class="searchable">
@@ -67,23 +63,31 @@
{% if node.status != 'unchanged' %} {% if node.status != 'unchanged' %}
<tr> <tr>
<td> <td>
<a href="{{url_for('report_latest', node_name=node.name)}}"> <a class="ui small status label
<span class="label label-status label-{{node.status}}">{{node.status}}</span> {% if node.status == 'failed' %}
red
{% elif node.status == 'changed' %}
green
{% elif node.status == 'unreported' %}
black
{% endif %}
" href="{{url_for('report_latest', node_name=node.name)}}">
{{node.status}}
</a> </a>
{% if node.status=='unreported'%} {% if node.status=='unreported'%}
<span class="label label-time label-unreported"> {{ node.unreported_time }} </label> <span class="ui small label status"> {{ node.unreported_time }} </label>
{% else %} {% else %}
{% if node.events['failures'] %}<span class="label label-important label-count">{{node.events['failures']}}</span>{% else %}<span class="label label-count">0</span>{% endif%} {% if node.events['failures'] %}<span class="ui small count label red">{{node.events['failures']}}</span>{% else %}<span class="ui small count label">0</span>{% endif%}
{% if node.events['successes'] %}<span class="label label-success label-count">{{node.events['successes']}}</span>{% else %}<span class="label label-count">0</span>{% endif%} {% if node.events['successes'] %}<span class="ui small count label green">{{node.events['successes']}}</span>{% else %}<span class="ui small count label">0</span>{% endif%}
{% endif %} {% endif %}
</td> </td>
<td><a href="{{url_for('node', node_name=node.name)}}">{{ node.name }}</a></td>
<td> <td>
{% if node.unreported_time != None or node.status != 'unreported' %} <a href="{{url_for('node', node_name=node.name)}}">{{ node.name }}</a>
<a class="btn btn-small btn-primary btn-lastreport" href="{{url_for('report_latest', node_name=node.name)}}">Latest Report</a> </td>
{% else %} <td>
<a class="btn btn-small btn-lastreport"> No Report </a> <a title="Latest Report" href="{{url_for('report_latest', node_name=node.name)}}">
{% endif %} <i class="large tasks purple icon"></i>
</a>
</td> </td>
</tr> </tr>
{% endif %} {% endif %}
@@ -92,11 +96,11 @@
</table> </table>
{% else %} {% else %}
<h2>Nodes status detail</h2> <h2>Nodes status detail</h2>
<div class="alert alert-info"> <div class="ui info message">
Nothing seems to be changing. Nothing seems to be changing.
</div> </div>
{% endif %} {% endif %}
</div> </div>
</div> </div>
</div> </div>
{% endblock row_fluid %} {% endblock content %}

View File

@@ -2,24 +2,18 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Puppet&#7427;oard</title> <title>Puppetboard</title>
<link href="//netdna.bootstrapcdn.com/bootswatch/2.3.2/flatly/bootstrap.min.css" rel="stylesheet"> <link href="//cdnjs.cloudflare.com/ajax/libs/semantic-ui/0.12.0/css/semantic.min.css" rel="stylesheet">
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css" rel="stylesheet"> <link href='//fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href="//cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.13.3/css/filter.formatter.css" rel="stylesheet">
<link href="{{ url_for('static', filename='css/puppetboard.css')}}" rel="stylesheet"> <link href="{{ url_for('static', filename='css/puppetboard.css')}}" rel="stylesheet">
</head> </head>
<body> <body>
<div style="font-variant:small-caps" class="navbar navbar-fixed-top"> <nav class="ui fixed purple inverted menu">
<div class="navbar-inner"> <div class="title item">
<div class="container"> Puppetboard
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> </div>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<span style="margin-top:-2px;" class="brand">Puppetboard</span>
<div class="nav-collapse collapse">
<ul class="nav">
{%- for endpoint, caption in [ {%- for endpoint, caption in [
('index', 'Overview'), ('index', 'Overview'),
('nodes', 'Nodes'), ('nodes', 'Nodes'),
@@ -28,40 +22,32 @@
('metrics', 'Metrics'), ('metrics', 'Metrics'),
('query', 'Query'), ('query', 'Query'),
] %} ] %}
<li{% if endpoint == request.endpoint %} class=active{% endif <a {% if endpoint == request.endpoint %} class="active item" {% else %} class="item" {% endif %}
%}><a href="{{ url_for(endpoint) }}">{{ caption }}</a></li> href="{{ url_for(endpoint) }}">{{ caption }}</a>
{%- endfor %} {%- endfor %}
</ul> </nav>
</div> <div class="ui grid padding-bottom">
</div> <div class="one wide column"></div>
</div> <div class="fourteen wide column">
</div>
{% block container %}
<div class="container-fluid" style="margin-bottom:55px;">
<div class="row-fluid">
{% block row_fluid %}
<div class="span12">
{% block content %} {% endblock content %} {% block content %} {% endblock content %}
</div> </div>
{% endblock row_fluid %} <div class="one wide column"></div>
</div>
</div>
{% endblock container %}
<div class="navbar navbar-fixed-bottom" style="background-color:rgb(249, 249, 249);">
<div class="navbar" style="height:55px;margin-bottom:0;">
<div class="container-fluid" style="line-height:55px;">
Copyright © 2013 <a href="https://github.com/daenney">Daniele Sluijters</a>. <span style="float:right">Live from PuppetDB.</span>
</div>
</div>
</div> </div>
<script src="//code.jquery.com/jquery-1.10.0.min.js"></script> <footer class="ui absolute fixed bottom">
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script> <div>
<script src="//cdn.jsdelivr.net/tablesorter/2.0.3/jquery.tablesorter.min.js"></script> Copyright © 2013-2014 <a href="https://github.com/daenney">Daniele Sluijters</a>. <span style="float:right">Live from PuppetDB.</span>
<script src="{{ url_for('static', filename='js/moment.js')}}"></script> </div>
</footer>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/semantic-ui/0.12.0/javascript/semantic.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.0/moment.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.13.3/jquery.tablesorter.min.js"></script>
<script src="{{ url_for('static', filename='js/timestamps.js')}}"></script> <script src="{{ url_for('static', filename='js/timestamps.js')}}"></script>
<script src="{{url_for('static', filename='js/tables.js')}}"></script>
<script src="{{url_for('static', filename='js/lists.js')}}"></script> <script src="{{url_for('static', filename='js/lists.js')}}"></script>
<script src="{{url_for('static', filename='js/tables.js')}}"></script>
{% block script %} {% endblock script %} {% block script %} {% endblock script %}
</body> </body>
</html> </html>

View File

@@ -2,11 +2,21 @@
{% block content %} {% block content %}
<div class="page-header"> <div class="page-header">
<h1>Metric <h1>Metric
{% set name = "%s&hellip;"|format(name[:75])|safe if name|length > 75%} {% if name|length > 75 %}
{% set name = "%s&hellip;"|format(name[:75])|safe %}
{% else %}
{% set name = name %}
{% endif %}
<small>{{name}}</small> <small>{{name}}</small>
</h1> </h1>
</div> </div>
<table class="table table-striped"> <table class="ui segment table">
<thead>
<tr>
<th>Option</th>
<th>Value</th>
</tr>
</thead>
<tbody> <tbody>
{% for key,value in metric %} {% for key,value in metric %}
<tr> <tr>

View File

@@ -1,37 +1,39 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% import '_macros.html' as macros %} {% import '_macros.html' as macros %}
{% block content %} {% block content %}
<div class="row-fluid"> <div class='ui two column grid'>
<div class="span12"> <div class='column'>
<div class='row'>
<h1>Details</h1> <h1>Details</h1>
<table class="table table-striped table-condensed" style="table-layout:fixed"> <table class="ui table compact basic">
<thead>
<tr>
<th>Hostname</th>
<th>Facts uploaded at</th>
<th>Catalog compiled at</th>
<th>Report uploaded at</th>
</tr>
</thead>
<tbody> <tbody>
<tr> <tr>
<th>Hostname</th>
<td style="word-wrap:break-word"><b>{{node.name}}</b></td> <td style="word-wrap:break-word"><b>{{node.name}}</b></td>
</tr>
<tr>
<th>Facts &nbsp;&nbsp;&nbsp;&nbsp;<i title='uploaded at' class=' upload icon'></i></th>
<td rel="utctimestamp">{{node.facts_timestamp}}</td> <td rel="utctimestamp">{{node.facts_timestamp}}</td>
</tr>
<tr>
<th>Catalog <i title='uploaded at' class=' upload icon'></i></th>
<td rel="utctimestamp">{{node.catalog_timestamp}}</td> <td rel="utctimestamp">{{node.catalog_timestamp}}</td>
</tr>
<tr>
<th>Report &nbsp;<i title='uploaded at' class=' upload icon'></i></th>
<td rel="utctimestamp">{{node.report_timestamp}}</td> <td rel="utctimestamp">{{node.report_timestamp}}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> <div class='row'>
<div class="row-fluid">
<div class="span6">
<h1>Facts</h1>
{{macros.facts_table(facts, link_facts=True, condensed=True, margin_top=10)}}
</div>
<div class="span6">
<h1>Reports</h1> <h1>Reports</h1>
{{ macros.reports_table(reports, node.name, condensed=True, hash_truncate=True, show_conf_col=False, show_agent_col=False, show_host_col=False)}} {{ macros.reports_table(reports, node.name, condensed=True, hash_truncate=True, show_conf_col=False, show_agent_col=False, show_host_col=False)}}
</div> </div>
</div> </div>
<div class='column'>
<h1>Facts</h1>
{{macros.facts_table(facts, link_facts=True, condensed=True)}}
</div>
</div>
{% endblock content %} {% endblock content %}

View File

@@ -1,56 +1,53 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block content %} {% block content %}
<div class="alert alert-info"> <div class="ui fluid icon input hide" style="margin-bottom:20px">
PuppetDB currently only returns active nodes. <input autofocus="autofocus" class="filter-table" placeholder="Type here to filter...">
</div> </div>
{% with messages = get_flashed_messages(with_categories=true) %} <table class='ui compact basic table nodes'>
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{category}}">
{{message}}
</div>
{% endfor %}
{% endif %}
{% endwith %}
<div class="hide" style="margin-bottom:20px">
<input autofocus="autofocus" style="width:100%" type="text" class="filter-table input-medium search-query" placeholder="Type here to filter">
</div>
<table class='nodes table table-striped table-condensed'>
<thead> <thead>
<tr> <tr>
<th>Status</th> <th>Status</th>
<th>Hostname</th> <th>Hostname</th>
<th>Catalog compiled at</th> <th>Catalog</th>
<th>Last report</th> <th>Report</th>
<th>&nbsp;</th> <th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
<tbody class="searchable"> <tbody class="searchable">
{% for node in nodes %} {% for node in nodes %}
<tr> <tr>
<td><a href="{{url_for('report_latest', node_name=node.name)}}"> <td>
<span class="label label-status label-{{ node.status }}">{{ node.status }}</span> <a class="ui small status label
{% if node.status == 'failed' %}
red
{% elif node.status == 'changed' %}
green
{% elif node.status == 'unreported' %}
black
{% endif %}
" href="{{url_for('report_latest', node_name=node.name)}}">
{{node.status}}
</a> </a>
{% if node.status=='unreported'%} {% if node.status=='unreported'%}
<span class="label label-time label-unreported"> {{ node.unreported_time }} </label> <span class="ui small label status"> {{ node.unreported_time }} </label>
{% else %} {% else %}
{% if node.events['failures'] %}<span class="label label-count label-important">{{node.events['failures']}}</span>{% else %}<span class="label label-count">0</span>{% endif%} <span>{% if node.events['failures'] %}<span class="ui small count label red">{{node.events['failures']}}</span>{% else %}<span class="ui small count label">0</span>{% endif%}
{% if node.events['successes'] %}<span class="label label-count label-success">{{node.events['successes']}}</span>{% else %}<span class="label label-count">0</span>{% endif%} {% if node.events['successes'] %}<span class="ui small count label green">{{node.events['successes']}}</span>{% else %}<span class="ui small count label">0</span>{% endif%}</span>
{% endif %} {% endif %}
</td> </td>
<td><a href="{{url_for('node', node_name=node.name)}}">{{node.name}}</a></td> <td><a href="{{url_for('node', node_name=node.name)}}">{{node.name}}</a></td>
<td rel="utctimestamp">{{node.catalog_timestamp}}</td> <td rel="utctimestamp">{{node.catalog_timestamp}}</td>
<td> <td>
{% if node.report_timestamp %} {% if node.report_timestamp %}
<span rel="utctimestamp">{{ node.report_timestamp }}</span> <a href="{{url_for('report_latest', node_name=node.name)}}" rel='utctimestamp'>{{ node.report_timestamp }}</a>
{% else %} {% else %}
<i class="icon icon-ban-circle"></i> <i class="large ban circle icon"></i>
{% endif %} {% endif %}
</td> </td>
<td> <td>
{% if node.report_timestamp %} {% if node.report_timestamp %}
<a class="btn btn-small btn-primary" href="{{url_for('report_latest', node_name=node.name)}}">Latest Report</a> <a title='Reports' href="{{url_for('reports_node', node=node.name)}}"><i class='large purple book icon'></i></a>
<a class="btn btn-small btn-primary" href="{{url_for('reports_node', node=node.name)}}">Reports</a> <i class='large purple trash icon'></i>
{% endif %} {% endif %}
</td> </td>
</tr> </tr>

View File

@@ -1,54 +1,37 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block row_fluid %} {% block content %}
<div class="span12">
<div class="alert">
This is highly experimental and will likely set your server on fire.
</div>
</div>
<div class="container" style="margin-bottom:55px;">
<div class="row">
<div class="span12">
<h2>Compose</h2> <h2>Compose</h2>
{% with messages = get_flashed_messages(with_categories=true) %} {% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %} {% if messages %}
{% for category, message in messages %} {% for category, message in messages %}
<div class="alert alert-{{category}}"> <div class="ui {{category}} message">
{{message}} {{message}}
</div> </div>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% endwith %} {% endwith %}
<form class="form-horizontal" method="POST" action="{{ url_for('query')}}"> <div class="ui form">
<form method="POST" action="{{ url_for('query')}}"
{{ form.csrf_token }} {{ form.csrf_token }}
<div class="control-group {% if form.query.errors %} error {% endif %}"> <div class="field {% if form.query.errors %} error {% endif %}">
{{form.query.label(class_="control-label")}} {{form.query(autofocus="autofocus", rows=5, placeholder="Enter your query: [\"=\", \"name\", \"hostname\"]. You may omit the opening and closing bracket.")}}
<div class="controls">
{{form.query(class_="input-block-level", autofocus="autofocus", rows=5, placeholder="\"=\", \"name\", \"hostname\"")}}
{% if form.query.errors %}
<span class="help-inline">{% for error in form.query.errors %}{{error}}{% endfor %}</span>
{% endif %}
</div> </div>
</div> <div class="inline fields">
<div class="control-group {% if form.endpoints.errors %} error {% endif %}">
{{form.endpoints.label(class_="control-label")}}
<div class="controls">
{% for subfield in form.endpoints %} {% for subfield in form.endpoints %}
{{subfield.label(class_="radio inline")}} <div class="field">
<div class="ui radio checkbox">
{{subfield }} {{subfield }}
{{subfield.label}}
</div>
</div>
{% endfor %} {% endfor %}
{% if form.endpoints.errors %}
<span class="help-inline">{% for error in form.endpoints.errors %}{{error}}{% endfor %}</span>
{% endif %}
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Yes I'm sure</button>
<button type="button" class="btn">No thanks</button>
</div> </div>
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<input type=submit class="ui purple submit button" value='Submit'>
<input type=reset class="ui red submit button" value='Cancel'>
</form> </form>
</div> </div>
</div>
{% if result %} {% if result %}
<div class="row"> <div class="row">
<div class="span12"> <div class="span12">
@@ -57,5 +40,4 @@
</div> </div>
</div> </div>
{% endif %} {% endif %}
</div> {% endblock content %}
{% endblock row_fluid %}

View File

@@ -1,7 +1,7 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block content %} {% block content %}
<h1>Summary</h1> <h1>Summary</h1>
<table class='table table-striped'> <table class='ui basic table'>
<thead> <thead>
<tr> <tr>
<th>Hostname</th> <th>Hostname</th>
@@ -27,7 +27,7 @@
</table> </table>
<h1>Events</h1> <h1>Events</h1>
<table class='table table-striped table-condensed'> <table class='ui basic table compact'>
<thead> <thead>
<tr> <tr>
<th>Resource</th> <th>Resource</th>
@@ -39,22 +39,22 @@
<tbody> <tbody>
{% for event in events %} {% for event in events %}
{% if not event.failed and event.item['old'] != event.item['new'] %} {% if not event.failed and event.item['old'] != event.item['new'] %}
<tr id='event-{{loop.index}}' class='success event'> <tr id='event-{{loop.index}}' class='positive'>
{% elif event.failed %} {% elif event.failed %}
<tr id='event-{{loop.index}}' class='error event'> <tr id='event-{{loop.index}}' class='error'>
{% endif %} {% endif %}
<td>{{event.item['type']}}[{{event.item['title']}}]</td> <td>{{event.item['type']}}[{{event.item['title']}}]</td>
<td>{{event.status}}</td> <td>{{event.status}}</td>
<td>{{event.item['old']}}</td> <td>{{event.item['old']}}</td>
<td>{{event.item['new']}}</td> <td>{{event.item['new']}}</td>
</tr> </tr>
<tr> {# <tr>
<td class='message' colspan='4'> <td class='message' colspan='4'>
<div id='message-event-{{loop.index}}'> <div id='message-event-{{loop.index}}'>
{{event.item['message']}} {{event.item['message']}}
</div> </div>
</td> </td>
</tr> </tr>#}
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>

View File

@@ -1,6 +1,6 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% block content %} {% block content %}
<div class="alert"> <div class="ui warning message">
Pending <a href="http://projects.puppetlabs.com/issues/21600">#21600</a>. You can access reports for a node or individual reports through the <a href="{{url_for('nodes')}}">Nodes</a> tab. Pending <a href="http://projects.puppetlabs.com/issues/21600">#21600</a>. You can access reports for a node or individual reports through the <a href="{{url_for('nodes')}}">Nodes</a> tab.
</div> </div>
{% endblock content %} {% endblock content %}