webapp: implemented dashboard.

This commit is contained in:
Shreyas Zare
2018-09-30 00:25:39 +05:30
parent cd660f2db3
commit cdd73b4a44
4 changed files with 391 additions and 13 deletions

View File

@@ -202,3 +202,65 @@ label {
width: 84%;
display: none;
}
.stats-panel {
height: 100px;
padding: 10px 0 10px 0;
}
.stats-panel .total-queries {
background-color: rgba(102, 153, 255, 0.7);
color: #ffffff;
}
.stats-panel .no-error {
background-color: rgba(92, 184, 92, 0.7);
color: #ffffff;
}
.stats-panel .server-failure {
background-color: rgba(217, 83, 79, 0.7);
color: #ffffff;
}
.stats-panel .name-error {
background-color: rgba(7, 7, 7, 0.7);
color: #ffffff;
}
.stats-panel .refused {
background-color: rgba(91, 192, 222, 0.7);
color: #ffffff;
}
.stats-panel .blocked {
background-color: rgba(255, 165, 0, 0.7);
color: #ffffff;
}
.stats-panel .clients {
background-color: rgba(51, 122, 183, 0.7);
color: #ffffff;
}
.stats-panel .stats-item {
width: 150px;
float: left;
padding: 10px;
margin-right: 8px;
}
.stats-panel .stats-item .number {
font-size: 22px;
font-weight: bold;
}
.stats-panel .stats-item .percentage {
font-size: 12px;
font-weight: bold;
}
.stats-panel .stats-item .title {
font-weight: bold;
}

View File

@@ -10,6 +10,7 @@
<link href="/css/bootstrap.min.css" rel="stylesheet">
<!--<link href="/css/bootstrap-theme.min.css" rel="stylesheet">-->
<script src="/js/bootstrap.min.js"></script>
<script src="/js/Chart.min.js"></script>
<link href="/css/font-awesome.min.css" rel="stylesheet" />
@@ -87,17 +88,160 @@
<div>
<ul class="nav nav-tabs" role="tablist">
<li id="mainPanelTabListZones" role="presentation" class="active"><a href="#mainPanelTabPaneZones" aria-controls="mainPanelTabPaneZones" role="tab" data-toggle="tab" onclick="return refreshZonesList();">Zones</a></li>
<li id="mainPanelTabListDashboard" role="presentation" class="active"><a href="#mainPanelTabPaneDashboard" aria-controls="mainPanelTabPaneDashboard" role="tab" data-toggle="tab" onclick="return refreshDashboard();">Dashboard</a></li>
<li id="mainPanelTabListZones" role="presentation"><a href="#mainPanelTabPaneZones" aria-controls="mainPanelTabPaneZones" role="tab" data-toggle="tab" onclick="return refreshZonesList();">Zones</a></li>
<li id="mainPanelTabListCachedZones" role="presentation"><a href="#mainPanelTabPaneCachedZones" aria-controls="mainPanelTabPaneCachedZones" role="tab" data-toggle="tab" onclick="return false;">Cached Zones</a></li>
<li id="mainPanelTabListBlockedZones" role="presentation"><a href="#mainPanelTabPaneBlockedZones" aria-controls="mainPanelTabPaneBlockedZones" role="tab" data-toggle="tab" onclick="return false;">Blocked Zones</a></li>
<li id="mainPanelTabListDnsClient" role="presentation"><a href="#mainPanelTabPaneDnsClient" aria-controls="mainPanelTabPaneZones" role="tab" data-toggle="tab" onclick="return false;">DNS Client</a></li>
<li id="mainPanelTabListDnsClient" role="presentation"><a href="#mainPanelTabPaneDnsClient" aria-controls="mainPanelTabPaneDnsClient" role="tab" data-toggle="tab" onclick="return false;">DNS Client</a></li>
<li id="mainPanelTabListSettings" role="presentation"><a href="#mainPanelTabPaneSettings" aria-controls="mainPanelTabPaneSettings" role="tab" data-toggle="tab" onclick="return loadDnsSettings();">Settings</a></li>
<li id="mainPanelTabListLogs" role="presentation"><a href="#mainPanelTabPaneLogs" aria-controls="mainPanelTabPaneLogs" role="tab" data-toggle="tab" onclick="return refreshLogFilesList();">Logs</a></li>
</ul>
<div class="tab-content">
<div id="mainPanelTabPaneZones" role="tabpanel" class="tab-pane active" style="padding: 10px 0 0 0;">
<div id="mainPanelTabPaneDashboard" role="tabpanel" class="tab-pane active" style="padding: 10px 0 0 0;">
<div id="divDashboardLoader" style="margin-top: 10px; height: 400px;"></div>
<div id="divDashboard" style="display: none;">
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-default active">
<input type="radio" name="optStatMode" id="optLastHour" autocomplete="off" checked> Last Hour
</label>
<label class="btn btn-default">
<input type="radio" name="optStatMode" id="optLastDay" autocomplete="off"> Last Day
</label>
<label class="btn btn-default">
<input type="radio" name="optStatMode" id="optLastWeek" autocomplete="off"> Last Week
</label>
<label class="btn btn-default">
<input type="radio" name="optStatMode" id="optLastMonth" autocomplete="off"> Last Month
</label>
</div>
<div class="stats-panel">
<div class="stats-item total-queries">
<div class="number" id="divDashboardStatsTotalQueries">100</div>
<div class="percentage">100%</div>
<div class="title">Total Queries</div>
</div>
<div class="stats-item no-error">
<div class="number" id="divDashboardStatsTotalNoError">70</div>
<div class="percentage" id="divDashboardStatsTotalNoErrorPercentage">0%</div>
<div class="title">No Error</div>
</div>
<div class="stats-item server-failure">
<div class="number" id="divDashboardStatsTotalServerFailure">5</div>
<div class="percentage" id="divDashboardStatsTotalServerFailurePercentage">0%</div>
<div class="title">Server Failure</div>
</div>
<div class="stats-item name-error">
<div class="number" id="divDashboardStatsTotalNameError">5</div>
<div class="percentage" id="divDashboardStatsTotalNameErrorPercentage">0%</div>
<div class="title">Name Error</div>
</div>
<div class="stats-item refused">
<div class="number" id="divDashboardStatsTotalRefused">10</div>
<div class="percentage" id="divDashboardStatsTotalRefusedPercentage">0%</div>
<div class="title">Refused</div>
</div>
<div class="stats-item blocked">
<div class="number" id="divDashboardStatsTotalBlocked">10</div>
<div class="percentage" id="divDashboardStatsTotalBlockedPercentage">0%</div>
<div class="title">Blocked</div>
</div>
<div class="stats-item clients">
<div class="number" id="divDashboardStatsTotalClients">10</div>
<div class="percentage">&nbsp;</div>
<div class="title">Clients</div>
</div>
</div>
<div>
<canvas id="canvasDashboardMain" style="margin: 10px 0 10px 0;"></canvas>
</div>
<div style="margin-top: 15px;">
<div class="panel panel-default" style="float: left; width: 547px; margin-bottom: 0px;">
<div class="panel-heading">Top Query Type</div>
<div class="panel-body">
<canvas id="canvasDashboardPie"></canvas>
</div>
</div>
<div class="panel panel-default" style="float: right; width: 547px; margin-bottom: 0px;">
<div class="panel-heading">Top Clients</div>
<table class="table table-hover" id="tableTopClients">
<thead>
<tr>
<th>Client</th>
<th>Queries</th>
</tr>
</thead>
<tbody>
<tr>
<td>127.0.0.1</td>
<td>100</td>
</tr>
<tr>
<td>::1</td>
<td>10</td>
</tr>
</tbody>
</table>
</div>
<div style="clear: both;"></div>
</div>
<div style="margin-top: 15px;">
<div class="panel panel-default" style="float: left; width: 547px; margin-bottom: 0px;">
<div class="panel-heading">Top Domains</div>
<table class="table table-hover" id="tableTopDomains">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
</tr>
</thead>
<tbody>
<tr>
<td>example.com</td>
<td>10</td>
</tr>
</tbody>
</table>
</div>
<div class="panel panel-default" style="float: right; width: 547px; margin-bottom: 0px;">
<div class="panel-heading">Top Blocked Domains</div>
<table class="table table-hover" id="tableTopBlockedDomains">
<thead>
<tr>
<th>Domain</th>
<th>Hits</th>
</tr>
</thead>
<tbody>
<tr>
<td>blocked.example.com</td>
<td>10</td>
</tr>
</tbody>
</table>
</div>
<div style="clear: both;"></div>
</div>
</div>
</div>
<div id="mainPanelTabPaneZones" role="tabpanel" class="tab-pane" style="padding: 10px 0 0 0;">
<div class="well well-sm zone-list-pane">
<form class="form-inline">
@@ -763,9 +907,9 @@
</div>
<div class="form-group" style="margin-bottom: 0px;">
<button id="btnSaveDnsSettings" type="button" class="btn btn-primary" data-loading-text="Saving..." onclick="return saveDnsSettings();" style="margin-right: 6px;">Save Settings</button>
<button id="btnFlushDnsCache" type="button" class="btn btn-warning" data-loading-text="Flushing..." onclick="return flushDnsCache();">Flush Cache</button>
<button id="btnFlushBlockedZone" type="button" class="btn btn-warning" data-loading-text="Flushing..." onclick="return flushBlockedZone();">Flush Blocked Zone</button>
<button id="btnSaveDnsSettings" type="button" class="btn btn-primary" data-loading-text="Saving..." onclick="return saveDnsSettings();">Save Settings</button>
<button id="btnFlushDnsCache" type="button" class="btn btn-warning" data-loading-text="Flushing..." onclick="return flushDnsCache();" style="margin-left: 6px;">Flush Cache</button>
<button id="btnFlushBlockedZone" type="button" class="btn btn-warning" data-loading-text="Flushing..." onclick="return flushBlockedZone();" style="margin-left: 6px;">Flush Blocked Zone</button>
</div>
</form>

10
DnsServerCore/www/js/Chart.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@

var token = null;
var refreshZonesTimerHandle;
var refreshTimerHandle;
function showPageLogin() {
hideAlert();
@@ -15,9 +15,9 @@ function showPageLogin() {
$("#txtUser").focus();
if (refreshZonesTimerHandle != null) {
clearInterval(refreshZonesTimerHandle);
refreshZonesTimerHandle = null;
if (refreshTimerHandle != null) {
clearInterval(refreshTimerHandle);
refreshTimerHandle = null;
}
}
@@ -32,8 +32,8 @@ function showPageMain(username) {
$(".nav-tabs li").removeClass("active");
$(".tab-pane").removeClass("active");
$("#mainPanelTabListZones").addClass("active");
$("#mainPanelTabPaneZones").addClass("active");
$("#mainPanelTabListDashboard").addClass("active");
$("#mainPanelTabPaneDashboard").addClass("active");
$("#divZoneViewer").hide();
@@ -50,12 +50,16 @@ function showPageMain(username) {
$("#pageMain").show();
loadDnsSettings();
refreshDashboard();
refreshZonesList();
refreshCachedZonesList();
refreshBlockedZonesList();
checkForUpdate();
refreshZonesTimerHandle = setInterval(function () { refreshZonesList(true); }, 60000);
refreshTimerHandle = setInterval(function () {
refreshDashboard(true);
refreshZonesList(true);
}, 60000);
}
$(function () {
@@ -571,6 +575,164 @@ function saveDnsSettings() {
return false;
}
function refreshDashboard(hideLoader) {
if (!$("#mainPanelTabPaneDashboard").hasClass("active"))
return;
if (hideLoader == null)
hideLoader = false;
var divDashboardLoader = $("#divDashboardLoader");
var divDashboard = $("#divDashboard");
if (!hideLoader) {
divDashboard.hide();
divDashboardLoader.show();
}
HTTPRequest({
url: "/api/getStats?token=" + token,
success: function (responseJSON) {
//stats
$("#divDashboardStatsTotalQueries").text(responseJSON.response.stats.totalQueries);
$("#divDashboardStatsTotalNoError").text(responseJSON.response.stats.totalNoError);
$("#divDashboardStatsTotalServerFailure").text(responseJSON.response.stats.totalServerFailure);
$("#divDashboardStatsTotalNameError").text(responseJSON.response.stats.totalNameError);
$("#divDashboardStatsTotalRefused").text(responseJSON.response.stats.totalRefused);
$("#divDashboardStatsTotalBlocked").text(responseJSON.response.stats.totalBlocked);
$("#divDashboardStatsTotalClients").text(responseJSON.response.stats.totalClients);
if (responseJSON.response.stats.totalQueries > 0) {
$("#divDashboardStatsTotalNoErrorPercentage").text((responseJSON.response.stats.totalNoError * 100 / responseJSON.response.stats.totalQueries).toFixed(2) + "%");
$("#divDashboardStatsTotalServerFailurePercentage").text((responseJSON.response.stats.totalServerFailure * 100 / responseJSON.response.stats.totalQueries).toFixed(2) + "%");
$("#divDashboardStatsTotalNameErrorPercentage").text((responseJSON.response.stats.totalNameError * 100 / responseJSON.response.stats.totalQueries).toFixed(2) + "%");
$("#divDashboardStatsTotalRefusedPercentage").text((responseJSON.response.stats.totalRefused * 100 / responseJSON.response.stats.totalQueries).toFixed(2) + "%");
$("#divDashboardStatsTotalBlockedPercentage").text((responseJSON.response.stats.totalBlocked * 100 / responseJSON.response.stats.totalQueries).toFixed(2) + "%");
}
else {
$("#divDashboardStatsTotalNoErrorPercentage").text("0%");
$("#divDashboardStatsTotalServerFailurePercentage").text("0%");
$("#divDashboardStatsTotalNameErrorPercentage").text("0%");
$("#divDashboardStatsTotalRefusedPercentage").text("0%");
$("#divDashboardStatsTotalBlockedPercentage").text("0%");
}
//main chart
if (window.chartDashboardMain == null) {
var contextDashboardMain = document.getElementById("canvasDashboardMain").getContext('2d');
window.chartDashboardMain = new Chart(contextDashboardMain, {
type: 'line',
data: responseJSON.response.mainChartData,
options: {
elements: {
line: {
tension: .5,
}
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
}
else {
window.chartDashboardMain.data = responseJSON.response.mainChartData;
window.chartDashboardMain.update();
}
//query type chart
if (window.chartDashboardPie == null) {
var contextDashboardPie = document.getElementById("canvasDashboardPie").getContext('2d');
window.chartDashboardPie = new Chart(contextDashboardPie, {
type: 'doughnut',
data: responseJSON.response.queryTypeChartData
});
}
else {
window.chartDashboardPie.data = responseJSON.response.queryTypeChartData;
window.chartDashboardPie.update();
}
//top clients
{
var tableHtml = "<thead><tr><th>Client</th><th>Queries</th></tr></thead><tbody>";
var topClients = responseJSON.response.topClients;
if (topClients.length < 1) {
tableHtml += "<tr><td>No Data</td><td></td></tr>";
}
else {
for (var i = 0; i < topClients.length; i++) {
tableHtml += "<tr><td>" + topClients[i].name + "</td><td>" + topClients[i].hits + "</td></tr>";
}
}
tableHtml += "</tbody>";
$("#tableTopClients").html(tableHtml);
}
//top domains
{
var tableHtml = "<thead><tr><th>Domain</th><th>Hits</th></tr></thead><tbody>";
var topDomains = responseJSON.response.topDomains;
if (topDomains.length < 1) {
tableHtml += "<tr><td>No Data</td><td></td></tr>";
}
else {
for (var i = 0; i < topDomains.length; i++) {
tableHtml += "<tr><td>" + topDomains[i].name + "</td><td>" + topDomains[i].hits + "</td></tr>";
}
}
tableHtml += "</tbody>";
$("#tableTopDomains").html(tableHtml);
}
//top blocked domains
{
var tableHtml = "<thead><tr><th>Domain</th><th>Hits</th></tr></thead><tbody>";
var topBlockedDomains = responseJSON.response.topBlockedDomains;
if (topBlockedDomains.length < 1) {
tableHtml += "<tr><td>No Data</td><td></td></tr>";
}
else {
for (var i = 0; i < topBlockedDomains.length; i++) {
tableHtml += "<tr><td>" + topBlockedDomains[i].name + "</td><td>" + topBlockedDomains[i].hits + "</td></tr>";
}
}
tableHtml += "</tbody>";
$("#tableTopBlockedDomains").html(tableHtml);
}
if (!hideLoader) {
divDashboardLoader.hide();
divDashboard.show();
}
},
invalidToken: function () {
showPageLogin();
},
objLoaderPlaceholder: divDashboardLoader,
dontHideAlert: hideLoader
});
return false;
}
function flushDnsCache() {
if (!confirm("Are you sure to flush the DNS Server cache?"))