Phase 4: Execution detail enhancements with re-run and download
Changes: - Added "Re-run Command" button to execution details modal - Added "Download Logs" button to export execution data as JSON - Re-run automatically switches to Quick Command tab and pre-fills form - Download includes all execution metadata and logs - Buttons only show for applicable execution types - Terminal-themed button styling Features: - Re-run: Quickly repeat a previous command on same worker - Download: Export execution logs for auditing/debugging - JSON format includes: execution_id, status, timestamps, logs - Filename includes execution ID and date for easy organization Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1085,7 +1085,21 @@
|
|||||||
html += formatLogEntry(log);
|
html += formatLogEntry(log);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add action buttons
|
||||||
|
html += '<div style="margin-top: 20px; padding-top: 15px; border-top: 1px solid var(--terminal-green); display: flex; gap: 10px;">';
|
||||||
|
|
||||||
|
// Re-run button (only for quick commands with command in logs)
|
||||||
|
const commandLog = execution.logs?.find(l => l.action === 'command_sent');
|
||||||
|
if (commandLog && commandLog.command) {
|
||||||
|
html += `<button onclick="rerunCommand('${escapeHtml(commandLog.command)}', '${commandLog.worker_id}')">[ 🔄 Re-run Command ]</button>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Download logs button
|
||||||
|
html += `<button onclick="downloadExecutionLogs('${executionId}')">[ 💾 Download Logs ]</button>`;
|
||||||
|
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
document.getElementById('executionDetails').innerHTML = html;
|
document.getElementById('executionDetails').innerHTML = html;
|
||||||
const modal = document.getElementById('viewExecutionModal');
|
const modal = document.getElementById('viewExecutionModal');
|
||||||
modal.dataset.executionId = executionId;
|
modal.dataset.executionId = executionId;
|
||||||
@@ -1169,6 +1183,52 @@
|
|||||||
return `${days}d ago`;
|
return `${days}d ago`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function rerunCommand(command, workerId) {
|
||||||
|
if (!confirm(`Re-run command: ${command}?`)) return;
|
||||||
|
|
||||||
|
closeModal('viewExecutionModal');
|
||||||
|
switchTab('quickcommand');
|
||||||
|
|
||||||
|
// Set the worker and command
|
||||||
|
document.getElementById('quickWorkerSelect').value = workerId;
|
||||||
|
document.getElementById('quickCommand').value = command;
|
||||||
|
|
||||||
|
// Scroll to the command field
|
||||||
|
document.getElementById('quickCommand').scrollIntoView({ behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function downloadExecutionLogs(executionId) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/api/executions/${executionId}`);
|
||||||
|
const execution = await response.json();
|
||||||
|
|
||||||
|
// Create downloadable JSON
|
||||||
|
const data = {
|
||||||
|
execution_id: executionId,
|
||||||
|
workflow_name: execution.workflow_name || '[Quick Command]',
|
||||||
|
status: execution.status,
|
||||||
|
started_by: execution.started_by,
|
||||||
|
started_at: execution.started_at,
|
||||||
|
completed_at: execution.completed_at,
|
||||||
|
logs: execution.logs
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create blob and download
|
||||||
|
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = `execution-${executionId}-${new Date().toISOString().split('T')[0]}.json`;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error downloading logs:', error);
|
||||||
|
alert('Error downloading execution logs');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function respondToPrompt(executionId, response) {
|
async function respondToPrompt(executionId, response) {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/executions/${executionId}/respond`, {
|
const res = await fetch(`/api/executions/${executionId}/respond`, {
|
||||||
|
|||||||
Reference in New Issue
Block a user