Feature search logs (#182)

* feature: search logs wip

* feature: Log search
This commit is contained in:
James Read 2023-10-25 22:29:41 +01:00 committed by GitHub
parent 5739091773
commit 912fd8089e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 5 deletions

View File

@ -35,9 +35,13 @@
</div>
<section id = "contentLogs" title = "Logs" hidden>
<div class = "toolbar">
<input placeholder = "Search for action name" id = "logSearchBox" />
<button id = "searchLogsClear" title = "Clear search filter" disabled>X</button>
</div>
<table title = "Logs">
<thead>
<tr>
<tr title = "untitled">
<th>Timestamp</th>
<th>Log</th>
<th>Exit Code</th>

View File

@ -30,7 +30,7 @@ export function marshalActionButtonsJsonToHtml (json) {
export function marshalLogsJsonToHtml (json) {
for (const logEntry of json.logs) {
const tpl = document.getElementById('tplLogRow')
const row = tpl.content.cloneNode(true)
const row = tpl.content.querySelector('tr').cloneNode(true)
if (logEntry.stdout.length === 0) {
logEntry.stdout = '(empty)'
@ -56,6 +56,7 @@ export function marshalLogsJsonToHtml (json) {
row.querySelector('pre.stdout').innerText = logEntry.stdout
row.querySelector('pre.stderr').innerText = logEntry.stderr
row.querySelector('.exit-code').innerText = logTableExitCode
row.setAttribute('title', logEntry.actionTitle)
for (const tag of logEntry.tags) {
const domTag = document.createElement('span')

View File

@ -3,6 +3,27 @@
import { marshalActionButtonsJsonToHtml, marshalLogsJsonToHtml } from './js/marshaller.js'
import { checkWebsocketConnection } from './js/websocket.js'
function searchLogs (e) {
document.getElementById('searchLogsClear').disabled = false
const searchText = e.target.value.toLowerCase()
for (const row of document.querySelectorAll('tr.log-row')) {
const actionTitle = row.getAttribute('title').toLowerCase()
row.hidden = !actionTitle.includes(searchText)
}
}
function searchLogsClear () {
for (const row of document.querySelectorAll('tr.log-row')) {
row.hidden = false
}
document.getElementById('searchLogsClear').disabled = true
document.getElementById('logSearchBox').value = ''
}
function showSection (name) {
for (const otherName of ['Actions', 'Logs']) {
document.getElementById('show' + otherName).classList.remove('activeSection')
@ -22,6 +43,11 @@ function setupSections () {
showSection('Actions')
}
function setupLogSearchBox () {
document.getElementById('logSearchBox').oninput = searchLogs
document.getElementById('searchLogsClear').onclick = searchLogsClear
}
function refreshLoop () {
if (window.websocketAvailable) {
// Websocket updates are streamed live, not updated on a loop.
@ -117,6 +143,7 @@ function processWebuiSettingsJson (settings) {
function main () {
setupSections()
setupLogSearchBox()
window.fetch('webUiSettings.json').then(res => {
return res.json()

View File

@ -232,9 +232,9 @@ action-button details summary div span:first-child {
padding: 0.2em;
background-color: #efefef;
border-top: 0;
border-left: 1px solid #999;
border-right: 1px solid #999;
border-bottom: 1px solid #999;
border-left: 1px solid #666;
border-right: 1px solid #666;
border-bottom: 1px solid #666;
}
execution-button button {
@ -404,6 +404,20 @@ span.tag {
padding: 0.2em;
}
div.toolbar {
padding: .4em;
text-align: left;
background-color: #efefef;
border: 1px solid #999;
border-bottom: 0;
display: flex;
flex-direction: row;
}
div.toolbar * {
margin-right: 1em;
}
@media (prefers-color-scheme: dark) {
body {
background-color: #333;
@ -472,4 +486,8 @@ span.tag {
tr:hover td {
background-color: #666;
}
div.toolbar {
background-color: black;
}
}