mirror of
https://github.com/nextcloud/all-in-one.git
synced 2026-04-17 05:36:58 -04:00
Previously it showed a lot of white space at the bottom, and the floating box didn't stick. Both is now fixed. AI-assistant: Copilot v1.0.7 (Claude Sonnet 4.6) Signed-off-by: Pablo Zmdl <pablo@nextcloud.com>
143 lines
4.7 KiB
JavaScript
143 lines
4.7 KiB
JavaScript
class LogViewer {
|
|
// Configure the interval in seconds for autoloading log data.
|
|
autoloadIntervalSec = 5;
|
|
// Set to true to see some debug log statements in the browser console.
|
|
debugLog = false;
|
|
|
|
// Don't touch these, please.
|
|
containerId;
|
|
apiBaseUrl = 'api/docker/logs';
|
|
autoloadIntervalId = null;
|
|
logElem;
|
|
lastLogTimestamp = '';
|
|
autoloadingDisabledFromButton = false;
|
|
loaderElem;
|
|
dataLoadingLock;
|
|
|
|
constructor() {
|
|
const id = document.body.dataset.containerId;
|
|
if (typeof(id) !== 'string' || !id.startsWith('nextcloud-aio-')) {
|
|
throw new Exception('Invalid container ID');
|
|
}
|
|
this.containerId = id;
|
|
this.logElem = document.querySelector('pre');
|
|
this.loaderElem = document.querySelector('.loader');
|
|
this.initAutoloadingControls();
|
|
// Enable automatic log data loading.
|
|
this.startAutoloading();
|
|
}
|
|
|
|
startAutoloading() {
|
|
// Load log data immediately.
|
|
this.loadAndAppendLogData();
|
|
// Load new log data repeatedly.
|
|
this.debug("Starting autoloading");
|
|
this.autoloadIntervalId = setInterval(() => {
|
|
if (this.isAutoloadingEnabled()) {
|
|
this.loadAndAppendLogData();
|
|
}
|
|
}, 5000);
|
|
}
|
|
|
|
stopAutoloading() {
|
|
this.debug("Stopping autoloading");
|
|
clearInterval(this.autoloadIntervalId);
|
|
this.autoloadIntervalId = null;
|
|
}
|
|
|
|
isAutoloadingEnabled() {
|
|
return !!this.autoloadIntervalId;
|
|
}
|
|
|
|
getUrl() {
|
|
return `${this.apiBaseUrl}?id=${this.containerId}&since=${this.lastLogTimestamp}`;
|
|
}
|
|
|
|
debug(...args) {
|
|
if (this.debugLog) {
|
|
console.debug('LogViewer:', ...args);
|
|
}
|
|
}
|
|
|
|
// Load log data and append it to the DOM.
|
|
loadAndAppendLogData() {
|
|
if (this.dataLoadingLock) {
|
|
this.debug("Another log data loading request is still running, cancelling this request");
|
|
return;
|
|
}
|
|
this.debug("Loading new log data");
|
|
this.dataLoadingLock = true;
|
|
this.loaderElem.classList.remove('hidden');
|
|
fetch(this.getUrl())
|
|
.then((response) => {
|
|
if (!response.ok) {
|
|
throw new Error("Error while fetching log data!");
|
|
}
|
|
return response;
|
|
})
|
|
.then((response) => response.text())
|
|
.then((text) => {
|
|
text = text.trim();
|
|
if (text.length === 0) {
|
|
this.debug("Received no new log data from server");
|
|
return;
|
|
}
|
|
this.debug("Received", Math.round(text.length / 1024), "KB of new log data from server");
|
|
this.logElem.append(text + "\n");
|
|
this.scrollToBottom();
|
|
this.lastLogTimestamp = text.split("\n").at(-1)?.split(' ')[0] ?? '';
|
|
})
|
|
.finally(() => {
|
|
this.dataLoadingLock = false;
|
|
this.loaderElem.classList.add('hidden');
|
|
this.debug("Finished log data loading");
|
|
})
|
|
.catch((err) => console.error(err));
|
|
}
|
|
|
|
scrollToBottom() {
|
|
this.logElem.scrollTop = this.logElem.scrollHeight;
|
|
}
|
|
|
|
initAutoloadingControls() {
|
|
// Provide a button that allows to manually disable the autoloading.
|
|
const button = document.getElementById('autoloading-control');
|
|
const statusElem = document.getElementById('autoloading-status');
|
|
if (!button) {
|
|
return;
|
|
}
|
|
button.addEventListener('click', (event) => {
|
|
event.preventDefault();
|
|
if (this.isAutoloadingEnabled()) {
|
|
this.stopAutoloading();
|
|
statusElem.textContent = 'disabled';
|
|
button.textContent = 'Enable';
|
|
this.autoloadingDisabledFromButton = true;
|
|
} else {
|
|
this.startAutoloading();
|
|
statusElem.textContent = 'enabled';
|
|
button.textContent = 'Disable';
|
|
this.autoloadingDisabledFromButton = false;
|
|
}
|
|
});
|
|
|
|
// Load new data immediately if the window gets visible to the user again (unless autoloading has been
|
|
// disabled).
|
|
document.addEventListener('visibilitychange', () => {
|
|
if (document.visibilityState === 'visible') {
|
|
this.debug("Window became visible");
|
|
if (!this.autoloadingDisabledFromButton) {
|
|
this.startAutoloading();
|
|
}
|
|
} else {
|
|
this.debug("Window became hidden");
|
|
this.stopAutoloading();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
new LogViewer();
|
|
});
|