Update launch_progress.js

This commit is contained in:
2025-06-16 15:46:19 +02:00
parent da75b4cd50
commit 04448e34c2

View File

@@ -111,6 +111,18 @@ function initializeSteps() {
</div>
`;
stepsContainer.appendChild(saveDataStep);
// Add Health Check step
const healthStep = document.createElement('div');
healthStep.className = 'step-item';
healthStep.innerHTML = `
<div class="step-icon"><i class="fas fa-heartbeat"></i></div>
<div class="step-content">
<h5>Health Check</h5>
<p class="step-status">Verifying instance health...</p>
</div>
`;
stepsContainer.appendChild(healthStep);
}
async function startLaunch(data) {
@@ -368,9 +380,39 @@ async function startLaunch(data) {
`;
saveDataStep.querySelector('.step-content').appendChild(instanceDetails);
// After saving instance data, add the health check step
await updateStep(9, 'Health Check', 'Verifying instance health...');
const healthResult = await checkInstanceHealth(`https://${data.webAddresses[0]}`);
if (!healthResult.success) {
throw new Error(`Health check failed: ${healthResult.error}`);
}
// Add a retry button if health check fails
const healthStep = document.querySelectorAll('.step-item')[8];
if (!healthResult.success) {
const retryButton = document.createElement('button');
retryButton.className = 'btn btn-sm btn-warning mt-2';
retryButton.innerHTML = '<i class="fas fa-sync-alt me-1"></i> Retry Health Check';
retryButton.onclick = async () => {
retryButton.disabled = true;
retryButton.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i> Checking...';
const retryResult = await checkInstanceHealth(`https://${data.webAddresses[0]}`);
if (retryResult.success) {
healthStep.classList.remove('failed');
healthStep.classList.add('completed');
retryButton.remove();
} else {
retryButton.disabled = false;
retryButton.innerHTML = '<i class="fas fa-sync-alt me-1"></i> Retry Health Check';
}
};
healthStep.querySelector('.step-content').appendChild(retryButton);
}
} catch (error) {
console.error('Launch failed:', error);
await updateStep(8, 'Saving Instance Data', `Error: ${error.message}`);
await updateStep(9, 'Health Check', `Error: ${error.message}`);
showError(error.message);
}
}
@@ -976,11 +1018,12 @@ function updateStep(stepNumber, title, description) {
document.getElementById('currentStep').textContent = title;
document.getElementById('stepDescription').textContent = description;
// Update progress bar
const progress = (stepNumber - 1) * 20;
// Calculate progress based on total number of steps (9 steps total)
const totalSteps = 9;
const progress = ((stepNumber - 1) / (totalSteps - 1)) * 100;
const progressBar = document.getElementById('launchProgress');
progressBar.style.width = `${progress}%`;
progressBar.textContent = `${progress}%`;
progressBar.textContent = `${Math.round(progress)}%`;
// Update step items
const steps = document.querySelectorAll('.step-item');
@@ -1185,3 +1228,78 @@ async function saveInstanceData(instanceData) {
throw error;
}
}
async function checkInstanceHealth(instanceUrl) {
const maxRetries = 5;
let currentAttempt = 1;
while (currentAttempt <= maxRetries) {
try {
// First get the instance ID from the database
const response = await fetch('/instances');
const text = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString(text, 'text/html');
// Find the instance row that matches our URL
const instanceRow = Array.from(doc.querySelectorAll('table tbody tr')).find(row => {
const urlCell = row.querySelector('td:nth-child(7) a'); // URL is in the 7th column
return urlCell && urlCell.textContent.trim() === instanceUrl;
});
if (!instanceRow) {
throw new Error('Instance not found in database');
}
// Get the instance ID from the status badge's data attribute
const statusBadge = instanceRow.querySelector('[data-instance-id]');
if (!statusBadge) {
throw new Error('Could not find instance ID');
}
const instanceId = statusBadge.dataset.instanceId;
// Now use the instance ID to check status
const statusResponse = await fetch(`/instances/${instanceId}/status`);
if (!statusResponse.ok) {
throw new Error(`Health check failed with status ${statusResponse.status}`);
}
const data = await statusResponse.json();
// Update the health check step
const healthStep = document.querySelectorAll('.step-item')[8]; // Adjust index based on your steps
healthStep.classList.remove('active');
healthStep.classList.add('completed');
const statusText = healthStep.querySelector('.step-status');
if (data.status === 'active') {
statusText.textContent = `Instance is healthy (Attempt ${currentAttempt}/${maxRetries})`;
return {
success: true,
data: data
};
} else {
throw new Error('Instance is not healthy');
}
} catch (error) {
console.error(`Health check attempt ${currentAttempt} failed:`, error);
// Update status to show current attempt
const healthStep = document.querySelectorAll('.step-item')[8];
const statusText = healthStep.querySelector('.step-status');
statusText.textContent = `Health check failed (Attempt ${currentAttempt}/${maxRetries}): ${error.message}`;
if (currentAttempt === maxRetries) {
return {
success: false,
error: `Health check failed after ${maxRetries} attempts: ${error.message}`
};
}
// Wait 5 seconds before next attempt
await new Promise(resolve => setTimeout(resolve, 5000));
currentAttempt++;
}
}
}