Files
headphones/data/interfaces/default/logs.html
Paul c835664014 Update logs.html
Modernised
2025-07-06 14:42:50 +01:00

178 lines
7.1 KiB
HTML

<%inherit file="base.html"/>
<%!
from headphones import helpers
%>
<%def name="headerIncludes()">
<div id="subhead_container">
<div id="subhead_menu">
<%-- Changed href to # and added data-action for JS handling --%>
<a class="menu_link_action" href="#" data-action="clearLogs" data-success="Logs cleared successfully!"><i class="fa fa-trash-o"></i> Clear log</a>
<a class="menu_link_action" href="#" data-action="toggleVerbose" data-success="Log verbosity toggled!"><i class="fa fa-pencil"></i> Toggle Debug Log</a>
</div>
</div>
</%def>
<%def name="body()">
<div id="paddingheader">
<h1 class="clearfix"><i class="fa fa-flag"></i> Logs</h1>
</div>
<table class="display" id="log_table">
<thead>
<tr>
<th class="column-timestamp">Timestamp</th>
<th class="column-level">Level</th>
<th class="column-message">Message</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<br>
<div class="refresh-controls" align="center">
Refresh rate:
<select id="refreshrate"> <%-- Removed inline onchange --%>
<option value="0" selected="selected">No Refresh</option>
<option value="5">5 Seconds</option>
<option value="15">15 Seconds</option>
<option value="30">30 Seconds</option>
<option value="60">60 Seconds</option>
<option value="300">5 Minutes</option>
<option value="600">10 Minutes</option>
</select>
</div>
</%def>
<%def name="headIncludes()">
${parent.headIncludes()} <%-- Ensure parent head includes are kept --%>
<link rel="stylesheet" href="interfaces/default/css/data_table.css">
<style>
/* Example CSS for log levels */
.gradeX { /* For ERROR */
background-color: #fdd; /* Light red */
}
.gradeW { /* For WARNING */
background-color: #ffc; /* Light yellow */
}
.gradeZ { /* For INFO/DEBUG */
/* default background or light gray */
}
</style>
</%def>
<%def name="javascriptIncludes()">
${parent.javascriptIncludes()} <%-- Ensure parent javascript includes are kept --%>
<script src="js/libs/jquery.dataTables.min.js"></script>
<script>
// Encapsulate page-specific logic
var LogsPage = LogsPage || {};
LogsPage.timer = null; // To hold the interval timer ID
LogsPage.initDataTable = function() {
$('#log_table').dataTable( {
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": 'getLog',
"sPaginationType": "full_numbers",
"aaSorting": [[0, 'desc']], // Sort by timestamp descending
"iDisplayLength": 25,
"bStateSave": true, // Retain table state across page loads
"oLanguage": {
"sSearch":"Filter:",
"sLengthMenu":"Show _MENU_ lines per page",
"sEmptyTable": "No log information available",
"sInfo":"Showing _START_ to _END_ of _TOTAL_ lines",
"sInfoEmpty":"Showing 0 to 0 of 0 lines",
"sInfoFiltered":"(filtered from _MAX_ total lines)"
},
"fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
// aData[1] contains the 'Level' from the server
if (aData[1] === "ERROR") {
$(nRow).addClass("gradeX");
} else if (aData[1] === "WARNING") {
$(nRow).addClass("gradeW");
} else {
$(nRow).addClass("gradeZ");
}
return nRow;
},
"fnDrawCallback": function (o) {
// Jump to top of page
$('html,body').scrollTop(0);
},
"fnServerData": function ( sSource, aoData, fnCallback ) {
// Custom function for fetching data, using $.getJSON
$.getJSON(sSource, aoData, function (json) {
fnCallback(json);
}).fail(function(jqXHR, textStatus, errorThrown) {
console.error("Error fetching log data:", textStatus, errorThrown);
// Optional: Display an error message to the user
});
}
});
};
LogsPage.setRefresh = function() {
var refreshrateSelect = document.getElementById('refreshrate');
if (refreshrateSelect != null) {
// Clear any existing timer
if (LogsPage.timer) {
clearInterval(LogsPage.timer);
}
var refreshValue = parseInt(refreshrateSelect.value, 10);
if (refreshValue !== 0) {
// Set a new interval to redraw the DataTable
LogsPage.timer = setInterval(function() {
$('#log_table').dataTable().fnDraw(false); // 'false' prevents resetting current page
}, 1000 * refreshValue);
}
}
};
LogsPage.initActions = function() {
// Event listener for the refresh rate dropdown
$('#refreshrate').on('change', LogsPage.setRefresh);
// Event delegation for header action links
$('#subhead_menu').on('click', '.menu_link_action', function(e) {
e.preventDefault(); // Prevent default link behavior
var $this = $(this);
var action = $this.data('action'); // 'clearLogs' or 'toggleVerbose'
var successMsg = $this.data('success');
if (typeof doAjaxCall === 'function') {
// Assuming doAjaxCall handles the AJAX request and success/error messages
doAjaxCall('/' + action, $this, 'table', successMsg, function() {
// Callback after successful AJAX call for specific actions
if (action === 'clearLogs') {
// Redraw table after clearing logs to show empty state or refreshed data
$('#log_table').dataTable().fnDraw();
}
// No specific redraw needed for toggleVerbose unless it changes displayed logs
});
} else {
console.error("doAjaxCall function is not defined. Cannot perform log action.");
// Fallback to direct navigation if AJAX utility is missing
// window.location.href = '/' + action;
}
});
};
$(document).ready(function() {
LogsPage.initDataTable();
LogsPage.initActions(); // Initialize new event handlers
// Initial call to set refresh based on default selected option
LogsPage.setRefresh();
// Ensure global initActions from common.js is called if it handles other site-wide actions
if (typeof initActions === 'function') {
initActions();
}
});
</script>
</%def>