/** * Pipeline Runner - Client Side Logic * Gestion de l'exécution des pipelines sauvegardés */ // État global const state = { pipelines: [], selectedPipeline: null, running: false }; // ==================== // INITIALIZATION // ==================== window.onload = async function() { await loadPipelinesList(); }; // Charger la liste des pipelines async function loadPipelinesList() { try { const response = await fetch('/api/pipeline/list'); const data = await response.json(); if (data.success) { state.pipelines = data.pipelines; renderPipelinesDropdown(); } } catch (error) { showStatus(`Erreur chargement pipelines: ${error.message}`, 'error'); } } // Rendre le dropdown de pipelines function renderPipelinesDropdown() { const select = document.getElementById('pipelineSelect'); select.innerHTML = ''; state.pipelines.forEach(pipeline => { const option = document.createElement('option'); option.value = pipeline.name; option.textContent = `${pipeline.name} (${pipeline.steps} étapes, ~${pipeline.estimatedDuration})`; select.appendChild(option); }); } // ==================== // PIPELINE LOADING // ==================== async function loadPipeline() { const select = document.getElementById('pipelineSelect'); const pipelineName = select.value; if (!pipelineName) { document.getElementById('pipelinePreview').style.display = 'none'; document.getElementById('btnRun').disabled = true; return; } try { const response = await fetch(`/api/pipeline/${pipelineName}`); const data = await response.json(); if (data.success) { state.selectedPipeline = data.pipeline; displayPipelinePreview(data.pipeline); document.getElementById('btnRun').disabled = false; } } catch (error) { showStatus(`Erreur chargement pipeline: ${error.message}`, 'error'); } } // Afficher la prévisualisation du pipeline function displayPipelinePreview(pipeline) { const preview = document.getElementById('pipelinePreview'); preview.style.display = 'block'; document.getElementById('pipelineName').textContent = pipeline.name; document.getElementById('pipelineDesc').textContent = pipeline.description || 'Pas de description'; document.getElementById('summarySteps').textContent = pipeline.pipeline.length; // Estimation durée const estimatedSeconds = pipeline.pipeline.length * 20; // Rough estimate const minutes = Math.floor(estimatedSeconds / 60); const seconds = estimatedSeconds % 60; document.getElementById('summaryDuration').textContent = minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`; // Liste des étapes const stepList = document.getElementById('stepList'); stepList.innerHTML = ''; pipeline.pipeline.forEach(step => { const div = document.createElement('div'); div.className = 'step-item'; div.textContent = `${step.step}. ${step.module} (${step.mode}) - Intensité: ${step.intensity}`; stepList.appendChild(div); }); } // ==================== // PIPELINE EXECUTION // ==================== async function runPipeline() { if (!state.selectedPipeline) { showStatus('Aucun pipeline sélectionné', 'error'); return; } if (state.running) { showStatus('Une exécution est déjà en cours', 'error'); return; } const rowNumber = parseInt(document.getElementById('rowNumber').value); if (!rowNumber || rowNumber < 2) { showStatus('Numéro de ligne invalide (minimum 2)', 'error'); return; } state.running = true; document.getElementById('btnRun').disabled = true; // Show progress section document.getElementById('progressSection').style.display = 'block'; document.getElementById('progressBar').style.display = 'block'; document.getElementById('progressText').style.display = 'block'; document.getElementById('resultsSection').style.display = 'none'; showStatus('🚀 Exécution du pipeline en cours...', 'loading'); updateProgress(0, 'Initialisation...'); try { const response = await fetch('/api/pipeline/execute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pipelineConfig: state.selectedPipeline, rowNumber: rowNumber }) }); updateProgress(50, 'Traitement en cours...'); const data = await response.json(); updateProgress(100, 'Terminé!'); if (data.success) { displayResults(data.result); showStatus('✅ Pipeline exécuté avec succès!', 'success'); } else { showStatus(`❌ Erreur: ${data.error}`, 'error'); } } catch (error) { showStatus(`❌ Erreur exécution: ${error.message}`, 'error'); console.error('Execution error:', error); } finally { state.running = false; document.getElementById('btnRun').disabled = false; setTimeout(() => { document.getElementById('progressSection').style.display = 'none'; }, 2000); } } // ==================== // RESULTS DISPLAY // ==================== function displayResults(result) { const resultsSection = document.getElementById('resultsSection'); resultsSection.style.display = 'block'; // Stats document.getElementById('statDuration').textContent = `${result.stats.totalDuration}ms`; document.getElementById('statSuccessSteps').textContent = `${result.stats.successfulSteps}/${result.stats.totalSteps}`; document.getElementById('statPersonality').textContent = result.stats.personality || 'N/A'; // Execution log const logContainer = document.getElementById('executionLog'); logContainer.innerHTML = ''; if (result.executionLog && result.executionLog.length > 0) { result.executionLog.forEach(logEntry => { const div = document.createElement('div'); div.className = `log-entry ${logEntry.success ? 'log-success' : 'log-error'}`; const status = logEntry.success ? '✓' : '✗'; const text = `${status} Étape ${logEntry.step}: ${logEntry.module} (${logEntry.mode}) ` + `- ${logEntry.duration}ms`; if (logEntry.modifications !== undefined) { div.textContent = text + ` - ${logEntry.modifications} modifs`; } else { div.textContent = text; } if (!logEntry.success && logEntry.error) { div.textContent += ` - Erreur: ${logEntry.error}`; } logContainer.appendChild(div); }); } else { logContainer.textContent = 'Aucun log d\'exécution disponible'; } } // ==================== // HELPERS // ==================== function updateProgress(percentage, text) { document.getElementById('progressFill').style.width = percentage + '%'; document.getElementById('progressText').textContent = text; } function showStatus(message, type) { const status = document.getElementById('status'); status.textContent = message; status.className = `status ${type}`; status.style.display = 'block'; if (type !== 'loading') { setTimeout(() => { status.style.display = 'none'; }, 5000); } }