// Mock data for demonstration const mockRuns = [ { runId: "cfe1e00a-1823-4fd7-bca7-3f99eccf3620", started_at: "2023-05-15T10:30:00Z", ended_at: "2023-05-15T10:35:23Z", status: "Completed", completed_nodes: 9, total_nodes: 9 }, { runId: "d2e4f6a8-b1c3-4d5e-7f8g-9h0i1j2k3l4m", started_at: "2023-05-15T11:15:00Z", ended_at: null, status: "Running", completed_nodes: 4, total_nodes: 9 }, { runId: "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6", started_at: "2023-05-14T09:45:00Z", ended_at: "2023-05-14T09:47:12Z", status: "Failed", completed_nodes: 2, total_nodes: 9 } ]; const mockRunDetails = { "cfe1e00a-1823-4fd7-bca7-3f99eccf3620": { runId: "cfe1e00a-1823-4fd7-bca7-3f99eccf3620", status: "Completed", nodes: [ { node_name: "search/kb", status: "success", input_json: { query: "VPN not connecting" }, output_json: { results: ["KB001", "KB042", "KB123"] }, timestamp: "2023-05-15T10:30:15Z" }, { node_name: "validate/kb", status: "success", input_json: { kb_ids: ["KB001", "KB042", "KB123"] }, output_json: { valid_ids: ["KB001", "KB123"] }, timestamp: "2023-05-15T10:31:02Z" }, // More nodes would be here... ] } }; document.addEventListener('DOMContentLoaded', () => { // Initialize UI renderRunsTable(); // Set up event listeners document.getElementById('newRunBtn').addEventListener('click', startNewRun); document.getElementById('closeModal').addEventListener('click', () => { document.getElementById('runModal').classList.add('hidden'); }); }); function renderRunsTable() { const tableBody = document.getElementById('runsTable'); tableBody.innerHTML = ''; mockRuns.forEach(run => { const row = document.createElement('tr'); // Status badge let statusBadge; switch(run.status) { case 'Completed': statusBadge = `Completed`; break; case 'Running': statusBadge = `Running`; break; case 'Failed': statusBadge = `Failed`; break; default: statusBadge = `Pending`; } // Progress bar const progressPercent = run.completed_nodes / run.total_nodes * 100; const progressBar = `
${run.completed_nodes}/${run.total_nodes} nodes
`; // Shortened run ID const shortRunId = run.runId.substring(0, 8) + '...'; row.innerHTML = ` ${shortRunId} ${new Date(run.started_at).toLocaleString()} ${statusBadge} ${progressBar} `; tableBody.appendChild(row); }); // Add event listeners to view buttons document.querySelectorAll('.view-run').forEach(button => { button.addEventListener('click', (e) => { const runId = e.target.closest('button').getAttribute('data-runid'); showRunDetails(runId); }); }); feather.replace(); }); function showRunDetails(runId) { const modal = document.getElementById('runModal'); const detailsContainer = document.getElementById('runDetails'); // In a real app, we would fetch this from the API const runDetails = mockRunDetails[runId] || { runId, status: "Running", nodes: [] }; // Render the flow diagram detailsContainer.innerHTML = `

Run ID: ${runDetails.runId}

Status: ${runDetails.status === 'Completed' ? 'Completed' : runDetails.status === 'Running' ? 'Running' : 'Failed'}

Execution Flow

${renderFlowDiagram(runDetails.nodes)}

Node Details

${runDetails.nodes.map(node => renderNodeDetails(node)).join('')}
`; modal.classList.remove('hidden'); feather.replace(); } function renderFlowDiagram(nodes) { const allNodes = [ "search/kb", "validate/kb", "search/web", "steps/perform", "script/generate", "email/send", "ticket/route", "ticket/create", "issue/auto-resolve" ]; let html = ''; for (let i = 0; i < allNodes.length; i++) { const nodeName = allNodes[i]; const nodeData = nodes.find(n => n.node_name === nodeName); // Determine node status let nodeStatus; if (nodeData) { nodeStatus = nodeData.status === 'success' ? 'success' : 'failed'; } else { nodeStatus = 'pending'; } // Node element html += `
${i+1}
${i < allNodes.length - 1 ? `
` : ''}
`; } return html; } function renderNodeDetails(node) { return `

${node.node_name}

${node.status}
${new Date(node.timestamp).toLocaleString()}
Input
${JSON.stringify(node.input_json, null, 2)}
Output
${JSON.stringify(node.output_json, null, 2)}
`; } function startNewRun() { // In a real app, this would call the API to start a new run alert('Starting a new SmartTriage run...'); // Then we would navigate to the run details page or refresh the list }