fix(tasks): use canonical section loader for task-log loading state

The task-log "Loading logs..." state rendered as a bare left-aligned text
line (or a tiny ad-hoc 16px spinner overlay), which read as unfinished next
to the rest of the UI. Swap all three log-loading spots (initial placeholder,
toggle-open fetch, running-task stream placeholder) to the canonical
window.lpLoadingBox('Loading logs…'), and scope .lp-loading inside the log
terminal box to fill it and drop its own card chrome so the spinner sits dead
centre over the terminal surface instead of a box-in-a-box. Widen the stream
overlay-removal selector to also clear .lp-loading.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
librelad 2026-07-18 20:04:56 +01:00
parent 641b152a82
commit 6fd7b0bf61
3 changed files with 19 additions and 4 deletions

View File

@ -640,6 +640,19 @@
border: 1px solid rgba(var(--text-rgb), 0.10);
}
/* Canonical section loader (window.lpLoadingBox) inside a task-log
terminal box: fill the whole container and centre the spinner over the
terminal surface, dropping the loader's own card chrome so it reads as
one panel rather than a box-in-a-box. */
.task-logs .log-container .lp-loading {
height: 100%;
min-height: 0;
margin: 0;
padding: 0;
background: none;
border: 0;
}
.meta-item {
display: flex;
align-items: baseline;

View File

@ -259,7 +259,7 @@ Object.assign(TasksManager.prototype, {
<div class="log-container terminal-style" id="logs-${task.id}" style="height: 200px; overflow-y: auto; position: relative;">
${hasLogs ?
task.log.map(log => `<div class="log-entry">${this.taskManager.parseAnsiColors(log)}</div>`).join('') :
'<div style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(10, 18, 36, 0.85); display: flex; align-items: center; justify-content: center; z-index: 10;"><div class="loading-spinner" style="width: 16px; height: 16px; border: 2px solid rgba(255,255,255,0.18); border-top: 2px solid #fff; border-radius: 50%; animation: spin 1s linear infinite; margin-right: 8px;"></div>Loading logs...</div></div>'
((typeof window.lpLoadingBox === 'function') ? window.lpLoadingBox('Loading logs…') : '<div class="log-entry">Loading logs…</div>')
}
</div>
</div>

View File

@ -22,7 +22,7 @@ Object.assign(TasksManager.prototype, {
const render = () => {
const logsContainer = document.getElementById(`logs-${taskId}`);
if (!logsContainer) return;
const overlay = logsContainer.querySelector('div[style*="position: absolute"]');
const overlay = logsContainer.querySelector('.lp-loading, div[style*="position: absolute"]');
if (overlay) overlay.remove();
let preElement = logsContainer.querySelector('pre.output-content');
if (!preElement) {
@ -114,7 +114,9 @@ Object.assign(TasksManager.prototype, {
return true;
};
logsContainer.innerHTML = '<div class="log-entry">🔄 Loading logs...</div>';
logsContainer.innerHTML = (typeof window.lpLoadingBox === 'function')
? window.lpLoadingBox('Loading logs…')
: '<div class="log-entry">Loading logs…</div>';
const isScrolledToBottom = logsContainer.scrollHeight - logsContainer.scrollTop <= logsContainer.clientHeight + 10;
const logResponse = await fetch(`/read-file?path=tasks/${taskId}.log`);
@ -276,7 +278,7 @@ Object.assign(TasksManager.prototype, {
const logsHtml = `
<div class="task-logs">
<div class="log-container terminal-style" id="logs-${taskId}" style="height: 200px; overflow-y: auto; position: relative;">
<div style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(10, 18, 36, 0.85); display: flex; align-items: center; justify-content: center; z-index: 10;"><div class="loading-spinner" style="width: 16px; height: 16px; border: 2px solid rgba(255,255,255,0.18); border-top: 2px solid #fff; border-radius: 50%; animation: spin 1s linear infinite; margin-right: 8px;"></div>Loading logs...</div></div>
${(typeof window.lpLoadingBox === 'function') ? window.lpLoadingBox('Loading logs…') : '<div class="log-entry">Loading logs…</div>'}
</div>
</div>
`;