285 lines
10 KiB
HTML
285 lines
10 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Loading Script - ScriptsManager</title>
|
|
|
|
<!-- Bootstrap CSS -->
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<!-- Bootstrap Icons -->
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css" rel="stylesheet">
|
|
|
|
<style>
|
|
.loading-container {
|
|
min-height: 100vh;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
}
|
|
|
|
.loading-card {
|
|
background: rgba(255, 255, 255, 0.95);
|
|
border-radius: 20px;
|
|
padding: 3rem;
|
|
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
|
|
text-align: center;
|
|
max-width: 500px;
|
|
width: 90%;
|
|
}
|
|
|
|
.loading-spinner {
|
|
width: 80px;
|
|
height: 80px;
|
|
margin: 0 auto 2rem;
|
|
}
|
|
|
|
.progress-bar-container {
|
|
background-color: #e9ecef;
|
|
border-radius: 10px;
|
|
height: 8px;
|
|
margin: 2rem 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.progress-bar {
|
|
background: linear-gradient(90deg, #667eea, #764ba2);
|
|
height: 100%;
|
|
border-radius: 10px;
|
|
transition: width 0.3s ease;
|
|
animation: pulse 2s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.7; }
|
|
}
|
|
|
|
.status-text {
|
|
color: #6c757d;
|
|
font-size: 1.1rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.script-info {
|
|
background-color: #f8f9fa;
|
|
border-radius: 10px;
|
|
padding: 1rem;
|
|
margin-top: 2rem;
|
|
}
|
|
|
|
.script-info h5 {
|
|
color: #495057;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.script-info p {
|
|
color: #6c757d;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.error-message {
|
|
background-color: #f8d7da;
|
|
color: #721c24;
|
|
border: 1px solid #f5c6cb;
|
|
border-radius: 10px;
|
|
padding: 1rem;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.open-anyway-btn {
|
|
margin-top: 1rem;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="loading-container">
|
|
<div class="loading-card">
|
|
<!-- Loading Spinner -->
|
|
<div class="spinner-border text-primary loading-spinner" role="status">
|
|
<span class="visually-hidden">Loading...</span>
|
|
</div>
|
|
|
|
<!-- Status Text -->
|
|
<h3 class="mb-3" id="loading-title">Starting Script...</h3>
|
|
<p class="status-text" id="status-text">Initializing script environment...</p>
|
|
|
|
<!-- Progress Bar -->
|
|
<div class="progress-bar-container">
|
|
<div class="progress-bar" id="progress-bar" style="width: 10%;"></div>
|
|
</div>
|
|
|
|
<!-- Script Information -->
|
|
<div class="script-info">
|
|
<h5>{{ script.display_name or script.filename }}</h5>
|
|
<p>{{ script.description or "Running script..." }}</p>
|
|
<small class="text-muted">
|
|
<i class="bi bi-folder me-1"></i>{{ script_group.name }} |
|
|
<i class="bi bi-person me-1"></i>{{ current_user.username }} |
|
|
<i class="bi bi-briefcase me-1"></i>{{ project.project_name }}
|
|
</small>
|
|
</div>
|
|
|
|
<!-- Error Container (hidden by default) -->
|
|
<div id="error-container" class="error-message" style="display: none;">
|
|
<i class="bi bi-exclamation-triangle me-2"></i>
|
|
<span id="error-text"></span>
|
|
<button type="button" class="btn btn-outline-danger btn-sm open-anyway-btn" onclick="openScriptAnyway()">
|
|
<i class="bi bi-box-arrow-up-right me-1"></i>
|
|
Open Script Anyway
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Bootstrap JS -->
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
|
|
<script>
|
|
// Configuration from backend
|
|
const SCRIPT_CONFIG = {
|
|
scriptId: {{ script.id }},
|
|
projectId: {{ project.id }},
|
|
userId: {{ current_user.id }},
|
|
proxyUrl: "{{ proxy_url }}",
|
|
fullProxyUrl: "{{ request.url_root.rstrip('/') }}{{ proxy_url }}",
|
|
maxAttempts: 30,
|
|
checkInterval: 2000
|
|
};
|
|
|
|
// Loading states and messages
|
|
const LOADING_STATES = [
|
|
{ progress: 10, title: "Starting Script...", message: "Initializing script environment..." },
|
|
{ progress: 25, title: "Loading Dependencies...", message: "Setting up required libraries..." },
|
|
{ progress: 40, title: "Configuring Environment...", message: "Preparing script workspace..." },
|
|
{ progress: 55, title: "Starting Web Server...", message: "Launching script interface..." },
|
|
{ progress: 70, title: "Checking Connectivity...", message: "Verifying script availability..." },
|
|
{ progress: 85, title: "Finalizing Setup...", message: "Almost ready..." },
|
|
{ progress: 95, title: "Script Ready!", message: "Redirecting to script interface..." }
|
|
];
|
|
|
|
let currentStateIndex = 0;
|
|
let attempts = 0;
|
|
let checkingStarted = false;
|
|
|
|
// DOM elements
|
|
const progressBar = document.getElementById('progress-bar');
|
|
const loadingTitle = document.getElementById('loading-title');
|
|
const statusText = document.getElementById('status-text');
|
|
const errorContainer = document.getElementById('error-container');
|
|
const errorText = document.getElementById('error-text');
|
|
|
|
// Update loading state
|
|
function updateLoadingState(stateIndex) {
|
|
if (stateIndex < LOADING_STATES.length) {
|
|
const state = LOADING_STATES[stateIndex];
|
|
progressBar.style.width = state.progress + '%';
|
|
loadingTitle.textContent = state.title;
|
|
statusText.textContent = state.message;
|
|
}
|
|
}
|
|
|
|
// Show error message
|
|
function showError(message) {
|
|
errorText.textContent = message;
|
|
errorContainer.style.display = 'block';
|
|
loadingTitle.textContent = "Error Starting Script";
|
|
statusText.textContent = "There was an issue starting the script.";
|
|
progressBar.style.width = '100%';
|
|
progressBar.style.backgroundColor = '#dc3545';
|
|
}
|
|
|
|
// Open script anyway (fallback)
|
|
function openScriptAnyway() {
|
|
window.location.href = SCRIPT_CONFIG.fullProxyUrl;
|
|
}
|
|
|
|
// Check if script is ready
|
|
async function checkScriptStatus() {
|
|
attempts++;
|
|
|
|
try {
|
|
// Update UI state periodically
|
|
if (!checkingStarted) {
|
|
checkingStarted = true;
|
|
// Start advancing through loading states
|
|
const stateInterval = setInterval(() => {
|
|
if (currentStateIndex < LOADING_STATES.length - 1) {
|
|
currentStateIndex++;
|
|
updateLoadingState(currentStateIndex);
|
|
} else {
|
|
clearInterval(stateInterval);
|
|
}
|
|
}, 3000);
|
|
}
|
|
|
|
// Check if script is responding
|
|
const response = await fetch(SCRIPT_CONFIG.fullProxyUrl, {
|
|
method: 'GET',
|
|
cache: 'no-cache'
|
|
});
|
|
|
|
if (response.ok) {
|
|
// Script is ready!
|
|
updateLoadingState(LOADING_STATES.length - 1);
|
|
setTimeout(() => {
|
|
window.location.href = SCRIPT_CONFIG.fullProxyUrl;
|
|
}, 1000);
|
|
return;
|
|
}
|
|
} catch (error) {
|
|
console.log(`Attempt ${attempts}: Script not ready yet`, error.message);
|
|
}
|
|
|
|
// Check if we've exceeded max attempts
|
|
if (attempts >= SCRIPT_CONFIG.maxAttempts) {
|
|
showError("Script is taking longer than expected to start. You can try opening it manually.");
|
|
return;
|
|
}
|
|
|
|
// Try again after interval
|
|
setTimeout(checkScriptStatus, SCRIPT_CONFIG.checkInterval);
|
|
}
|
|
|
|
// Start checking when page loads
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Start with first loading state
|
|
updateLoadingState(0);
|
|
|
|
// Start script execution via AJAX first
|
|
startScriptExecution();
|
|
|
|
// Begin checking script status after a short delay
|
|
setTimeout(checkScriptStatus, 3000);
|
|
});
|
|
|
|
// Function to start script execution
|
|
async function startScriptExecution() {
|
|
try {
|
|
const response = await fetch(`/api/scripts/${SCRIPT_CONFIG.scriptId}/execute`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
parameters: {}
|
|
})
|
|
});
|
|
|
|
const result = await response.json();
|
|
|
|
if (result.success) {
|
|
console.log('Script execution started successfully:', result);
|
|
} else {
|
|
console.error('Failed to start script:', result.message);
|
|
showError(result.message || 'Failed to start script');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error starting script execution:', error);
|
|
showError('Error starting script: ' + error.message);
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |