instance launching (fake)
This commit is contained in:
344
templates/main/launch_progress.html
Normal file
344
templates/main/launch_progress.html
Normal file
@@ -0,0 +1,344 @@
|
||||
{% extends "common/base.html" %}
|
||||
{% from "components/header.html" import header %}
|
||||
|
||||
{% block title %}Launching Instance - DocuPulse{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{{ header(
|
||||
title="Launching Instance",
|
||||
description="Setting up your new DocuPulse instance",
|
||||
icon="fa-rocket"
|
||||
) }}
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="text-center mb-4">
|
||||
<div class="spinner-border text-primary mb-3" role="status" style="width: 3rem; height: 3rem;">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
<h4 id="currentStep">Initializing...</h4>
|
||||
<p class="text-muted" id="stepDescription">Preparing to launch your instance</p>
|
||||
</div>
|
||||
|
||||
<div class="progress mb-4" style="height: 25px;">
|
||||
<div class="progress-bar progress-bar-striped progress-bar-animated"
|
||||
role="progressbar"
|
||||
id="launchProgress"
|
||||
style="width: 0%">0%</div>
|
||||
</div>
|
||||
|
||||
<div class="launch-steps">
|
||||
<div class="step-item" data-step="1">
|
||||
<div class="step-icon"><i class="fas fa-code-branch"></i></div>
|
||||
<div class="step-content">
|
||||
<h5>Cloning Repository</h5>
|
||||
<p class="step-status">Waiting...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="step-item" data-step="2">
|
||||
<div class="step-icon"><i class="fas fa-server"></i></div>
|
||||
<div class="step-content">
|
||||
<h5>Creating Container</h5>
|
||||
<p class="step-status">Waiting...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="step-item" data-step="3">
|
||||
<div class="step-icon"><i class="fas fa-network-wired"></i></div>
|
||||
<div class="step-content">
|
||||
<h5>Configuring Network</h5>
|
||||
<p class="step-status">Waiting...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="step-item" data-step="4">
|
||||
<div class="step-icon"><i class="fas fa-database"></i></div>
|
||||
<div class="step-content">
|
||||
<h5>Setting Up Database</h5>
|
||||
<p class="step-status">Waiting...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="step-item" data-step="5">
|
||||
<div class="step-icon"><i class="fas fa-paint-brush"></i></div>
|
||||
<div class="step-content">
|
||||
<h5>Applying Customization</h5>
|
||||
<p class="step-status">Waiting...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="step-item" data-step="6">
|
||||
<div class="step-icon"><i class="fas fa-check-circle"></i></div>
|
||||
<div class="step-content">
|
||||
<h5>Finalizing Setup</h5>
|
||||
<p class="step-status">Waiting...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-4">
|
||||
<div id="errorContainer" class="alert alert-danger" style="display: none;">
|
||||
<h5><i class="fas fa-exclamation-triangle"></i> Error</h5>
|
||||
<p id="errorMessage"></p>
|
||||
<button class="btn btn-outline-danger" onclick="retryLaunch()">
|
||||
<i class="fas fa-redo"></i> Retry
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.launch-steps {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.step-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1.5rem;
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
background-color: #f8f9fa;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.step-item.active {
|
||||
background-color: #e3f2fd;
|
||||
}
|
||||
|
||||
.step-item.completed {
|
||||
background-color: #e8f5e9;
|
||||
}
|
||||
|
||||
.step-item.failed {
|
||||
background-color: #ffebee;
|
||||
}
|
||||
|
||||
.step-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background-color: #e9ecef;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 1rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.step-item.active .step-icon {
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.step-item.completed .step-icon {
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.step-item.failed .step-icon {
|
||||
background-color: #dc3545;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.step-content {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.step-content h5 {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.step-status {
|
||||
margin: 0;
|
||||
font-size: 0.875rem;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
.step-item.completed .step-status {
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
.step-item.failed .step-status {
|
||||
color: #dc3545;
|
||||
}
|
||||
</style>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Get the launch data from sessionStorage
|
||||
const launchData = JSON.parse(sessionStorage.getItem('instanceLaunchData'));
|
||||
if (!launchData) {
|
||||
showError('No launch data found. Please start over.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Start the launch process
|
||||
startLaunch(launchData);
|
||||
});
|
||||
|
||||
async function startLaunch(data) {
|
||||
try {
|
||||
// Step 1: Clone Repository
|
||||
await updateStep(1, 'Cloning Repository', 'Fetching code from repository...');
|
||||
const cloneResult = await cloneRepository(data.repository, data.branch);
|
||||
if (!cloneResult.success) throw new Error(cloneResult.error);
|
||||
|
||||
// Step 2: Create Container
|
||||
await updateStep(2, 'Creating Container', 'Setting up Docker container...');
|
||||
const containerResult = await createContainer(data);
|
||||
if (!containerResult.success) throw new Error(containerResult.error);
|
||||
|
||||
// Step 3: Configure Network
|
||||
await updateStep(3, 'Configuring Network', 'Setting up network and ports...');
|
||||
const networkResult = await configureNetwork(data);
|
||||
if (!networkResult.success) throw new Error(networkResult.error);
|
||||
|
||||
// Step 4: Setup Database
|
||||
await updateStep(4, 'Setting Up Database', 'Initializing database...');
|
||||
const dbResult = await setupDatabase(data);
|
||||
if (!dbResult.success) throw new Error(dbResult.error);
|
||||
|
||||
// Step 5: Apply Customization
|
||||
await updateStep(5, 'Applying Customization', 'Applying your custom settings...');
|
||||
const customResult = await applyCustomization(data);
|
||||
if (!customResult.success) throw new Error(customResult.error);
|
||||
|
||||
// Step 6: Finalize
|
||||
await updateStep(6, 'Finalizing Setup', 'Completing the setup...');
|
||||
const finalResult = await finalizeSetup(data);
|
||||
if (!finalResult.success) throw new Error(finalResult.error);
|
||||
|
||||
// Launch complete
|
||||
completeLaunch();
|
||||
} catch (error) {
|
||||
showError(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
function updateStep(stepNumber, title, description) {
|
||||
return new Promise((resolve) => {
|
||||
// Update the current step in the header
|
||||
document.getElementById('currentStep').textContent = title;
|
||||
document.getElementById('stepDescription').textContent = description;
|
||||
|
||||
// Update progress bar
|
||||
const progress = (stepNumber - 1) * 20;
|
||||
const progressBar = document.getElementById('launchProgress');
|
||||
progressBar.style.width = `${progress}%`;
|
||||
progressBar.textContent = `${progress}%`;
|
||||
|
||||
// Update step items
|
||||
document.querySelectorAll('.step-item').forEach((item, index) => {
|
||||
const step = index + 1;
|
||||
item.classList.remove('active', 'completed', 'failed');
|
||||
|
||||
if (step < stepNumber) {
|
||||
item.classList.add('completed');
|
||||
item.querySelector('.step-status').textContent = 'Completed';
|
||||
} else if (step === stepNumber) {
|
||||
item.classList.add('active');
|
||||
item.querySelector('.step-status').textContent = description;
|
||||
}
|
||||
});
|
||||
|
||||
// Simulate some work being done
|
||||
setTimeout(resolve, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
function showError(message) {
|
||||
const errorContainer = document.getElementById('errorContainer');
|
||||
const errorMessage = document.getElementById('errorMessage');
|
||||
|
||||
errorMessage.textContent = message;
|
||||
errorContainer.style.display = 'block';
|
||||
|
||||
// Update the current step to show error
|
||||
const currentStep = document.querySelector('.step-item.active');
|
||||
if (currentStep) {
|
||||
currentStep.classList.add('failed');
|
||||
currentStep.querySelector('.step-status').textContent = 'Failed: ' + message;
|
||||
}
|
||||
}
|
||||
|
||||
function completeLaunch() {
|
||||
// Update progress to 100%
|
||||
const progressBar = document.getElementById('launchProgress');
|
||||
progressBar.style.width = '100%';
|
||||
progressBar.textContent = '100%';
|
||||
|
||||
// Mark all steps as completed
|
||||
document.querySelectorAll('.step-item').forEach(item => {
|
||||
item.classList.add('completed');
|
||||
item.querySelector('.step-status').textContent = 'Completed';
|
||||
});
|
||||
|
||||
// Update header
|
||||
document.getElementById('currentStep').textContent = 'Launch Complete!';
|
||||
document.getElementById('stepDescription').textContent = 'Your instance is ready to use';
|
||||
|
||||
// Show success message and redirect button
|
||||
const successMessage = document.createElement('div');
|
||||
successMessage.className = 'alert alert-success text-center mt-4';
|
||||
successMessage.innerHTML = `
|
||||
<h5><i class="fas fa-check-circle"></i> Success!</h5>
|
||||
<p>Your instance has been successfully launched.</p>
|
||||
<a href="/instances" class="btn btn-success">
|
||||
<i class="fas fa-arrow-right"></i> Go to Instances
|
||||
</a>
|
||||
`;
|
||||
document.querySelector('.card-body').appendChild(successMessage);
|
||||
|
||||
// Clear the launch data from sessionStorage
|
||||
sessionStorage.removeItem('instanceLaunchData');
|
||||
}
|
||||
|
||||
function retryLaunch() {
|
||||
// Reload the page to start over
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// Mock API functions (replace these with actual API calls)
|
||||
async function cloneRepository(repo, branch) {
|
||||
// Simulate API call
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
async function createContainer(data) {
|
||||
// Simulate API call
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
async function configureNetwork(data) {
|
||||
// Simulate API call
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
async function setupDatabase(data) {
|
||||
// Simulate API call
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
async function applyCustomization(data) {
|
||||
// Simulate API call
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
async function finalizeSetup(data) {
|
||||
// Simulate API call
|
||||
return { success: true };
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user