librelad 1b0040dbf1 refactor(tasks): decompose tasks-manager god-file into 8 responsibility files
Faithful brace-aware split of tasks-manager.js (2664->491 line base) into
list-render, data-load, log-stream, row-expand, actions, modals, logs-modal,
format — augmenting TasksManager.prototype. First removed 4 provably-dead
duplicate defs (the earlier init/setupAutoRefresh/startLogStreaming/loadTaskLogs
that the later defs already overrode — behavior-preserving). Methods relocated
verbatim via a brace-aware Node extractor (handles strings/templates/comments/
regex, fixing the line-heuristic over-capture). Verified: all 60 (deduped)
methods present exactly once, no dups, all 9 files node --check clean. Wired
after the base in the task-system loader (async=false-ordered).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-30 14:53:19 +01:00

105 lines
4.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Auto-extracted from tasks-manager.js (verbatim) — augments TasksManager.prototype. Loaded after the base.
Object.assign(TasksManager.prototype, {
async viewTaskLogs(taskId) {
// Open logs in a modal or new view
const task = this.tasks.find(t => t.id === taskId);
if (!task) return;
// Load full logs for modal
const fullLogs = await this.taskManager.readFullTaskLog(taskId);
// Create modal with streaming logs
const modal = document.createElement('div');
modal.className = 'task-logs-modal';
modal.innerHTML = `
<div class="modal-overlay" onclick="closeTaskLogsModal()"></div>
<div class="modal-content">
<div class="modal-header">
<h3>📋 Task Logs - ${task.id}</h3>
<div class="log-status">
<span class="status-indicator" id="log-status-${taskId}">Loading...</span>
<button class="log-toggle" id="log-toggle-${taskId}" onclick="toggleLogStreaming('${taskId}')">⏸️ Pause</button>
</div>
<button class="modal-close" onclick="closeTaskLogsModal()">×</button>
</div>
<div class="modal-body">
<div class="task-info-summary">
<div class="info-row">
<strong>Command:</strong> <code>${task.command}</code>
</div>
<div class="info-row">
<strong>Status:</strong> <span class="status-${task.status || 'unknown'}">${this.getStatusIcon(task.status)} ${task.status ? task.status.toUpperCase() : 'UNKNOWN'}</span>
</div>
<div class="info-row">
<strong>Created:</strong> ${new Date(task.createdAt).toLocaleString()}
</div>
</div>
<div class="logs-section">
<h4>Execution Logs <span class="log-line-count">(0 lines)</span></h4>
<div class="log-viewer terminal-style" id="log-viewer-${taskId}">
${fullLogs.split('\n').map(log => `<div class="log-line">${this.taskManager.parseAnsiColors(log)}</div>`).join('')}
</div>
</div>
${task.output ? `
<div class="output-section">
<h4>Command Output</h4>
<pre class="output-viewer">${this.taskManager.parseAnsiColors(task.output)}</pre>
</div>
` : ''}
${task.error ? `
<div class="error-section">
<h4>Error Details</h4>
<pre class="error-viewer">${this.escapeHtml(task.error)}</pre>
</div>
` : ''}
</div>
</div>
`;
document.body.appendChild(modal);
// Update line count
const lineCount = fullLogs.split('\n').length;
const lineCountElement = modal.querySelector('.log-line-count');
if (lineCountElement) {
lineCountElement.textContent = `(${lineCount} lines)`;
}
// Start streaming if task is running
if (task.status === 'running' || task.status === 'queued') {
this.startLogStreaming(taskId, modal);
}
// Store streaming controller
this.activeLogStreams = this.activeLogStreams || new Map();
},
toggleLogStreaming(taskId) {
const streamData = this.activeLogStreams?.get(taskId);
if (!streamData) return;
const toggleButton = document.getElementById(`log-toggle-${taskId}`);
const statusIndicator = document.getElementById(`log-status-${taskId}`);
if (streamData.isPaused) {
// Resume streaming
streamData.isPaused = false;
if (toggleButton) toggleButton.textContent = '⏸️ Pause';
if (statusIndicator) {
statusIndicator.textContent = '🔴 Live';
statusIndicator.className = 'status-indicator live';
}
} else {
// Pause streaming
streamData.isPaused = true;
if (toggleButton) toggleButton.textContent = '▶️ Resume';
if (statusIndicator) {
statusIndicator.textContent = '⏸️ Paused';
statusIndicator.className = 'status-indicator paused';
}
}
},
});