Spaces:
Running
Running
{% extends "base.html" %} | |
{% block content %} | |
<div class="card mb-4"> | |
<div class="card-header"> | |
<h2 class="card-title mb-0">{{ title }}</h2> | |
</div> | |
<div class="card-body"> | |
<p>The inventory synchronization process has started. Please keep this page open until it completes. This may take a few minutes.</p> | |
<div id="progress-container"> | |
<div class="progress" role="progressbar" aria-label="Sync Progress" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="height: 25px;"> | |
<div class="progress-bar progress-bar-striped progress-bar-animated" id="progressBar" style="width: 0%">0%</div> | |
</div> | |
<p class="mt-2 text-center" id="progress-message">Initializing...</p> | |
</div> | |
<h4 class="mt-4">Live Log:</h4> | |
<pre id="log-output" class="prettyprint" style="height: 300px; overflow-y: scroll; background-color: #282c34;"><code class="language-bash"></code></pre> | |
<div id="results-container" class="d-none"> | |
<h3>Synchronization Complete</h3> | |
<h4 id="final-subtitle" class="text-muted"></h4> | |
<pre class="prettyprint"><code id="final-code" class="language-javascript"></code></pre> | |
</div> | |
</div> | |
</div> | |
<script> | |
document.addEventListener('DOMContentLoaded', function() { | |
const progressBar = document.getElementById('progressBar'); | |
const progressMessage = document.getElementById('progress-message'); | |
const logOutput = document.querySelector('#log-output code'); | |
const progressContainer = document.getElementById('progress-container'); | |
const resultsContainer = document.getElementById('results-container'); | |
const finalSubtitle = document.getElementById('final-subtitle'); | |
const finalCode = document.getElementById('final-code'); | |
const eventSource = new EventSource("{{ url_for('zoho.fetch_inventory_stream') }}"); | |
let logContent = ''; | |
eventSource.onmessage = function(event) { | |
const data = JSON.parse(event.data); | |
progressBar.style.width = data.progress + '%'; | |
progressBar.textContent = data.progress + '%'; | |
progressBar.setAttribute('aria-valuenow', data.progress); | |
progressMessage.textContent = data.message.split('\n')[0]; // Show only first line of message | |
const timestamp = new Date().toLocaleTimeString(); | |
logContent += `[${timestamp}] ${data.message}\n`; | |
logOutput.textContent = logContent; | |
logOutput.parentElement.scrollTop = logOutput.parentElement.scrollHeight; | |
if (data.status === 'complete' || data.status === 'error') { | |
eventSource.close(); | |
progressBar.classList.remove('progress-bar-animated', 'progress-bar-striped'); | |
if(data.status === 'complete') { | |
progressBar.classList.add('bg-success'); | |
finalSubtitle.textContent = data.message; | |
finalCode.textContent = data.final_code; | |
Prism.highlightElement(finalCode); | |
progressContainer.classList.add('d-none'); | |
resultsContainer.classList.remove('d-none'); | |
} else { | |
progressBar.classList.add('bg-danger'); | |
progressMessage.textContent = "An error occurred. Check the log for details."; | |
} | |
} | |
}; | |
eventSource.onerror = function(err) { | |
console.error("EventSource failed:", err); | |
progressMessage.textContent = 'Error: Connection to the server was lost.'; | |
progressBar.classList.add('bg-danger'); | |
progressBar.classList.remove('progress-bar-animated', 'progress-bar-striped'); | |
eventSource.close(); | |
}; | |
}); | |
</script> | |
{% endblock %} |