1
0
mirror of https://github.com/jhillyerd/inbucket.git synced 2025-12-17 17:47:03 +00:00

More bootstrap work, status page now updates

This commit is contained in:
James Hillyerd
2015-08-18 22:58:29 -07:00
parent da28a8ee55
commit 5623ac1e8e
7 changed files with 157 additions and 165 deletions

View File

@@ -1,3 +1,4 @@
/* Site Wide */
html {
position: relative;
min-height: 100%;
@@ -9,11 +10,6 @@ body {
margin-bottom: 60px;
}
.mailbox-header {
text-align: center;
font-size: 18px;
}
.footer {
position: absolute;
bottom: 0;
@@ -27,12 +23,14 @@ body {
margin: 20px 0;
}
.message-controls {
padding: 10px 0;
/* Mailbox & Messages */
.mailbox-header {
text-align: center;
font-size: 18px;
}
#emailContent {
padding-bottom: 20px;
.message-controls {
padding: 0 0 10px 0;
}
.message-header dl {
@@ -49,31 +47,20 @@ body {
}
}
.message-body {
padding: 0 5px;
}
.message-attachments {
margin-top: 20px;
padding: 10px 20px;;
}
.message-attachments ul {
margin: 0
}
#emailSubject {
border-bottom: 1px #606060 solid;
margin: 0;
width: 617px;
}
#emailBody {
color: #555;
margin-top: 15px;
}
.errors {
background-color: #ffa0a0;
color: #333;
padding: 5px 10px;
}
/* Metrics */
table.metrics {
}
@@ -90,27 +77,3 @@ table.metrics {
width: 200px;
}
#emailAttachments {
border-collapse: collapse;
}
#emailAttachments th, #emailAttachments td {
text-align: left;
padding: 0 3px 3px 0;
}
#emailAttachments .fileName:before {
content: '\203A\00A0';
}
#emailAttachments a {
background: #8ac6dc;
color: #fff;
text-decoration: none;
padding: 0 5px;
}
#emailAttachments a:hover {
background: #becf74;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -27,8 +27,8 @@
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="/" accesskey="1">Home</a></li>
<li><a href="/status" accesskey="2">Status</a></li>
<li id="nav-mail"><a href="/" accesskey="1">Mail</a></li>
<li id="nav-status"><a href="/status" accesskey="2">Status</a></li>
</ul>
<form class="navbar-form navbar-right" action="{{reverse "MailboxIndex"}}" method="GET">
<div class="form-group">

View File

@@ -2,26 +2,26 @@
{{$id := .message.Id}}
<div class="btn-group btn-group-sm message-controls" role="group" aria-label="Message Controls">
<button type="button"
class="btn btn-default"
class="btn btn-primary"
onClick="window.open('/link/{{$name}}/{{$id}}');">
<span class="glyphicon glyphicon-link" aria-hidden="true"></span>
Link
</button>
<button type="button"
class="btn btn-default"
class="btn btn-danger"
onClick="deleteMessage('{{.message.Id}}');">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
Delete
</button>
<button type="button"
class="btn btn-default"
class="btn btn-primary"
onClick="messageSource('{{.message.Id}}');">
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
Source
</button>
{{if .htmlAvailable}}
<button type="button"
class="btn btn-default"
class="btn btn-primary"
onClick="htmlView('{{.message.Id}}');">
<span class="glyphicon glyphicon-new-window" aria-hidden="true"></span>
HTML
@@ -29,7 +29,8 @@
{{end}}
</div>
<div class="well well-sm message-header">
<div class="panel panel-default message-header">
<div class="panel-body">
<dl class="dl-horizontal">
<dt>From:</dt>
<dd>{{.message.From}}</dd>
@@ -39,22 +40,35 @@
<dd>{{.message.Subject}}</dd>
</dl>
</div>
</div>
<div id="message-body">{{.body}}</div>
<div class="message-body">{{.body}}</div>
{{with .attachments}}
<div class="panel panel-default message-attachments">
<div class="panel-body">
<div class="well message-attachments">
<ul class="list-unstyled">
{{range $i, $e := .}}
<li>
<span class="glyphicon glyphicon-paperclip" aria-hidden="true"></span>
{{$e.FileName}}
({{$e.ContentType}})
<a href="/mailbox/vattach/{{$name}}/{{$id}}/{{$i}}/{{$e.FileName}}" target="_blank">View</a>
<a href="/mailbox/dattach/{{$name}}/{{$id}}/{{$i}}/{{$e.FileName}}">Download</a>
<a class="btn btn-success btn-sm"
role="button"
href="/mailbox/vattach/{{$name}}/{{$id}}/{{$i}}/{{$e.FileName}}"
target="_blank"
aria-label="View">
<span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span>
View
</a>
<a class="btn btn-primary btn-sm"
role="button"
hhref="/mailbox/dattach/{{$name}}/{{$id}}/{{$i}}/{{$e.FileName}}"
aria-label="Download">
<span class="glyphicon glyphicon-download" aria-hidden="true"></span>
Download
</a>
</li>
{{end}}
</ul>
</div>
</div>
{{end}}

View File

@@ -1,49 +1,50 @@
{{define "title"}}{{printf "Inbucket for %v" .name}}{{end}}
{{define "navMail"}}true{{end}}
{{$name := .name}}
{{define "script"}}
<script>
var selected = "{{.selected}}"
var selected = "{{.selected}}";
function messageLoaded(responseText, textStatus, XMLHttpRequest) {
if (textStatus == "error") {
alert("Failed to load message, server said:\n" + responseText)
alert("Failed to load message, server said:\n" + responseText);
} else {
window.scrollTo(0,0)
window.scrollTo(0,0);
}
}
function listLoaded() {
$('.listEntry').click(
function() {
$('.listEntry').removeClass("disabled")
$(this).addClass("disabled")
$('#emailContent').load('/mailbox/{{.name}}/' + this.id, messageLoaded)
selected = this.id
$('.listEntry').removeClass("disabled");
$(this).addClass("disabled");
$('#emailContent').load('/mailbox/{{.name}}/' + this.id, messageLoaded);
selected = this.id;
}
)
$("#messageList").slideDown()
$("#messageList").slideDown();
if (selected != "") {
$("#" + selected).click()
selected = ""
$("#" + selected).click();
selected = "";
}
}
function loadList() {
$('#messageList').load("/mailbox/{{.name}}", listLoaded)
$('#messageList').load("/mailbox/{{.name}}", listLoaded);
}
function reloadList() {
$('#messageList').hide()
loadList()
$('#messageList').hide();
loadList();
}
function listInit() {
$("#messageList").hide()
loadList()
$("#messageList").hide();
loadList();
}
function deleteMessage(id) {
$('#emailContent').empty()
$('#emailContent').empty();
$.ajax({
type: 'DELETE',
url: '/mailbox/{{.name}}/' + id,
@@ -54,21 +55,26 @@
function htmlView(id) {
window.open('/mailbox/{{.name}}/' + id + "/html", '_blank',
'width=800,height=600,' +
'menubar=yes,resizable=yes,scrollbars=yes,status=yes,toolbar=yes')
'menubar=yes,resizable=yes,scrollbars=yes,status=yes,toolbar=yes');
}
function messageSource(id) {
window.open('/mailbox/{{.name}}/' + id + "/source", '_blank',
'width=800,height=600,' +
'menubar=no,resizable=yes,scrollbars=yes,status=no,toolbar=no')
'menubar=no,resizable=yes,scrollbars=yes,status=no,toolbar=no');
}
$(document).ready(listInit)
function docReady() {
$('#nav-mail').addClass("active");
listInit();
}
$(document).ready(docReady)
</script>
{{end}}
{{define "content"}}
<div class="panel panel-primary">
<div class="panel panel-info">
<div class="panel-heading mailbox-header">
<span class="glyphicon glyphicon-inbox" aria-hidden="true"></span>
{{.name}}

View File

@@ -2,32 +2,33 @@
{{define "script"}}
<script src="/public/jquery.sparkline.min.js" type="text/javascript" charset="utf-8"></script>
<script src="/public/jquery.color-2.1.2.min.js" type="text/javascript" charset="utf-8"></script>
<script>
jQuery.ajaxSetup({ cache: false })
flashOn = jQuery.Color("rgba(255,255,0,1)")
flashOff = jQuery.Color("rgba(255,255,0,0)")
dataHist = new Object()
jQuery.ajaxSetup({ cache: false });
flashOn = jQuery.Color("rgba(255,255,0,1)");
flashOff = jQuery.Color("rgba(255,255,0,0)");
dataHist = new Object();
function timeFilter(seconds) {
if (seconds < 60) {
return seconds + " seconds"
return seconds + " seconds";
} else if (seconds < 3600) {
return (seconds/60).toFixed(0) + " minute(s)"
return (seconds/60).toFixed(0) + " minute(s)";
} else if (seconds < 86400) {
return (seconds/3600).toFixed(1) + " hour(s)"
return (seconds/3600).toFixed(1) + " hour(s)";
}
return (seconds/86400).toFixed(0) + " day(s)"
return (seconds/86400).toFixed(0) + " day(s)";
}
function sizeFilter(bytes) {
if (bytes < 1024) {
return bytes + " bytes"
return bytes + " bytes";
} else if (bytes < 1048576) {
return (bytes/1024).toFixed(0) + " KB"
return (bytes/1024).toFixed(0) + " KB";
} else if (bytes < 1073741824) {
return (bytes/1048576).toFixed(2) + " MB"
return (bytes/1048576).toFixed(2) + " MB";
}
return (bytes/1073741824).toFixed(2) + " GB"
return (bytes/1073741824).toFixed(2) + " GB";
}
function numberFilter(x) {
@@ -37,101 +38,102 @@
}
function appendHistory(name, value) {
var h = dataHist[name]
var h = dataHist[name];
if (! h) {
h = new Array(0)
h = new Array(0);
}
// Prevent array from growing
if (h.length >= 60) {
h = h.slice(1,60)
h = h.slice(1,60);
}
h.push(parseInt(value))
dataHist[name] = h
el = $('#s-' + name)
h.push(parseInt(value));
dataHist[name] = h;
el = $('#s-' + name);
if (el) {
el.sparkline(dataHist[name])
el.sparkline(dataHist[name]);
}
}
// Show spikes for numbers that only increase
function setHistoryOfActivity(name, value) {
var h = value.split(",")
var prev = parseInt(h[0])
var h = value.split(",");
var prev = parseInt(h[0]);
for (i=0; i<h.length; i++) {
var t = parseInt(h[i])
h[i] = t-prev
prev = t
var t = parseInt(h[i]);
h[i] = t-prev;
prev = t;
}
// First value will always be zero
if (h.length > 0) {
h = h.slice(1)
h = h.slice(1);
}
el = $('#s-' + name)
el = $('#s-' + name);
if (el) {
el.sparkline(h)
el.sparkline(h);
}
}
// Show up/down for numbers that can decrease
function setHistoryOfCount(name, value) {
var h = value.split(",")
el = $('#s-' + name)
var h = value.split(",");
el = $('#s-' + name);
if (el) {
el.sparkline(h)
el.sparkline(h);
}
}
function metric(name, value, filter, chartable) {
if (chartable) {
appendHistory(name, value)
appendHistory(name, value);
}
if (filter) {
value = filter(value)
value = filter(value);
}
var el = $('#m-' + name)
if (el.text() != value) {
el.text(value)
el.css('background-color', flashOn)
el.animate({ backgroundColor: flashOff }, 1500)
el.text(value);
el.css('background-color', flashOn);
el.animate({ backgroundColor: flashOff }, 1500);
}
}
function displayMetrics(data, textStatus, jqXHR) {
// Non graphing
metric('uptime', data.uptime, timeFilter, false)
metric('retentionScanCompleted', data.retention.SecondsSinceScanCompleted, timeFilter, false)
metric('retentionPeriod', data.retention.Period, timeFilter, false)
metric('uptime', data.uptime, timeFilter, false);
metric('retentionScanCompleted', data.retention.SecondsSinceScanCompleted, timeFilter, false);
metric('retentionPeriod', data.retention.Period, timeFilter, false);
// JavaScript history
metric('memstatsSys', data.memstats.Sys, sizeFilter, true)
metric('memstatsHeapAlloc', data.memstats.HeapAlloc, sizeFilter, true)
metric('memstatsHeapSys', data.memstats.HeapSys, sizeFilter, true)
metric('memstatsHeapObjects', data.memstats.HeapObjects, numberFilter, true)
metric('smtpConnectsCurrent', data.smtp.ConnectsCurrent, numberFilter, true)
metric('memstatsSys', data.memstats.Sys, sizeFilter, true);
metric('memstatsHeapAlloc', data.memstats.HeapAlloc, sizeFilter, true);
metric('memstatsHeapSys', data.memstats.HeapSys, sizeFilter, true);
metric('memstatsHeapObjects', data.memstats.HeapObjects, numberFilter, true);
metric('smtpConnectsCurrent', data.smtp.ConnectsCurrent, numberFilter, true);
// Server-side history
metric('smtpReceivedTotal', data.smtp.ReceivedTotal, numberFilter, false)
setHistoryOfActivity('smtpReceivedTotal', data.smtp.ReceivedHist)
metric('smtpConnectsTotal', data.smtp.ConnectsTotal, numberFilter, false)
setHistoryOfActivity('smtpConnectsTotal', data.smtp.ConnectsHist)
metric('smtpWarnsTotal', data.smtp.WarnsTotal, numberFilter, false)
setHistoryOfActivity('smtpWarnsTotal', data.smtp.WarnsHist)
metric('smtpErrorsTotal', data.smtp.ErrorsTotal, numberFilter, false)
setHistoryOfActivity('smtpErrorsTotal', data.smtp.ErrorsHist)
metric('retentionDeletesTotal', data.retention.DeletesTotal, numberFilter, false)
setHistoryOfActivity('retentionDeletesTotal', data.retention.DeletesHist)
metric('retainedCurrent', data.retention.RetainedCurrent, numberFilter, false)
setHistoryOfCount('retainedCurrent', data.retention.RetainedHist)
metric('smtpReceivedTotal', data.smtp.ReceivedTotal, numberFilter, false);
setHistoryOfActivity('smtpReceivedTotal', data.smtp.ReceivedHist);
metric('smtpConnectsTotal', data.smtp.ConnectsTotal, numberFilter, false);
setHistoryOfActivity('smtpConnectsTotal', data.smtp.ConnectsHist);
metric('smtpWarnsTotal', data.smtp.WarnsTotal, numberFilter, false);
setHistoryOfActivity('smtpWarnsTotal', data.smtp.WarnsHist);
metric('smtpErrorsTotal', data.smtp.ErrorsTotal, numberFilter, false);
setHistoryOfActivity('smtpErrorsTotal', data.smtp.ErrorsHist);
metric('retentionDeletesTotal', data.retention.DeletesTotal, numberFilter, false);
setHistoryOfActivity('retentionDeletesTotal', data.retention.DeletesHist);
metric('retainedCurrent', data.retention.RetainedCurrent, numberFilter, false);
setHistoryOfCount('retainedCurrent', data.retention.RetainedHist);
}
function loadMetrics() {
// jQuery.getJSON( url [, data] [, success(data, textStatus, jqXHR)] )
jQuery.getJSON('/debug/vars', null, displayMetrics)
jQuery.getJSON('/debug/vars', null, displayMetrics);
}
function aboutInit() {
loadMetrics()
setInterval(loadMetrics, 10000)
$('#navStatus').addClass('active');
loadMetrics();
setInterval(loadMetrics, 10000);
}
$(document).ready(aboutInit)