first commit
This commit is contained in:
197
static/js/progress.js
Normal file
197
static/js/progress.js
Normal file
@@ -0,0 +1,197 @@
|
||||
let progressInterval = null;
|
||||
|
||||
function startProgressPolling() {
|
||||
if (progressInterval) {
|
||||
clearInterval(progressInterval);
|
||||
}
|
||||
|
||||
progressInterval = setInterval(async () => {
|
||||
try {
|
||||
const response = await fetch('/api/progress');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.active) {
|
||||
updateProgressUI(data.message, data.progress, data.total);
|
||||
} else {
|
||||
stopProgressPolling();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Progress polling error:', error);
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function stopProgressPolling() {
|
||||
if (progressInterval) {
|
||||
clearInterval(progressInterval);
|
||||
progressInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
function updateProgressUI(message, progress, total) {
|
||||
const progressSection = document.getElementById('progressSection');
|
||||
const progressBar = progressSection.querySelector('.progress-bar');
|
||||
const progressMessage = document.getElementById('progressMessage');
|
||||
const progressPercentage = document.getElementById('progressPercentage');
|
||||
|
||||
const percentage = total > 0 ? Math.round((progress / total) * 100) : 0;
|
||||
progressBar.style.width = percentage + '%';
|
||||
|
||||
if (progressPercentage) {
|
||||
progressPercentage.textContent = percentage + '%';
|
||||
}
|
||||
|
||||
progressBar.setAttribute('aria-valuenow', percentage);
|
||||
|
||||
if (progressMessage) {
|
||||
progressMessage.textContent = message;
|
||||
}
|
||||
}
|
||||
|
||||
function showProgress() {
|
||||
const progressSection = document.getElementById('progressSection');
|
||||
const progressBar = progressSection.querySelector('.progress-bar');
|
||||
const progressMessage = document.getElementById('progressMessage');
|
||||
const progressPercentage = document.getElementById('progressPercentage');
|
||||
|
||||
progressBar.style.width = '0%';
|
||||
if (progressPercentage) {
|
||||
progressPercentage.textContent = '0%';
|
||||
}
|
||||
if (progressMessage) {
|
||||
progressMessage.textContent = 'Initializing...';
|
||||
}
|
||||
|
||||
document.getElementById('resultSection').style.display = 'none';
|
||||
progressSection.style.display = 'block';
|
||||
document.getElementById('generateBtn').disabled = true;
|
||||
|
||||
startProgressPolling();
|
||||
}
|
||||
|
||||
function hideProgress() {
|
||||
const progressSection = document.getElementById('progressSection');
|
||||
progressSection.style.display = 'none';
|
||||
document.getElementById('generateBtn').disabled = false;
|
||||
|
||||
stopProgressPolling();
|
||||
}
|
||||
|
||||
function showResult(message, type = 'danger') {
|
||||
const resultSection = document.getElementById('resultSection');
|
||||
const resultMessage = document.getElementById('resultMessage');
|
||||
const alertDiv = resultSection.querySelector('.alert');
|
||||
|
||||
const iconMap = {
|
||||
'success': 'check-circle',
|
||||
'danger': 'exclamation-circle',
|
||||
'warning': 'exclamation-triangle',
|
||||
'info': 'info-circle'
|
||||
};
|
||||
|
||||
const icon = iconMap[type] || 'info-circle';
|
||||
|
||||
alertDiv.className = `alert alert-${type}`;
|
||||
resultMessage.innerHTML = `<i class="fas fa-${icon} me-2"></i>${message}`;
|
||||
resultSection.style.display = 'block';
|
||||
|
||||
if (type === 'success') {
|
||||
setTimeout(() => {
|
||||
resultSection.style.display = 'none';
|
||||
}, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const form = document.getElementById('generateForm');
|
||||
if (form) {
|
||||
form.addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = getFormData();
|
||||
|
||||
if (!formData) {
|
||||
showResult('Please select at least one country to continue', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
await downloadConfiguration(formData);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
async function downloadConfiguration(formData) {
|
||||
showProgress();
|
||||
|
||||
try {
|
||||
const endpoint = formData.app_type === 'raw-cidr'
|
||||
? '/api/generate/raw'
|
||||
: '/api/generate';
|
||||
|
||||
const response = await fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(formData)
|
||||
});
|
||||
|
||||
hideProgress();
|
||||
|
||||
if (response.ok) {
|
||||
const fromCache = response.headers.get('X-From-Cache') === 'true';
|
||||
const generatedAt = response.headers.get('X-Generated-At');
|
||||
|
||||
const blob = await response.blob();
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
|
||||
const contentDisposition = response.headers.get('Content-Disposition');
|
||||
let filename = 'geoblock_config.conf';
|
||||
if (contentDisposition) {
|
||||
const filenameMatch = contentDisposition.match(/filename="?(.+)"?/);
|
||||
if (filenameMatch) {
|
||||
filename = filenameMatch[1];
|
||||
}
|
||||
}
|
||||
|
||||
a.download = filename;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
document.body.removeChild(a);
|
||||
|
||||
if (fromCache) {
|
||||
showResult(`<i class="fas fa-bolt"></i> <strong>Lightning fast!</strong> Downloaded from cache: ${filename}`, 'success');
|
||||
} else {
|
||||
showResult(`Configuration downloaded successfully: ${filename}`, 'success');
|
||||
}
|
||||
} else {
|
||||
const error = await response.json();
|
||||
showResult(error.error || 'An error occurred during download', 'danger');
|
||||
}
|
||||
} catch (error) {
|
||||
hideProgress();
|
||||
showResult('Network error: ' + error.message, 'danger');
|
||||
}
|
||||
}
|
||||
|
||||
function getFormData() {
|
||||
const countries = Array.from(document.querySelectorAll('input[name="countries"]:checked'))
|
||||
.map(input => input.value);
|
||||
|
||||
if (countries.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const useCacheCheckbox = document.getElementById('useCache');
|
||||
|
||||
return {
|
||||
countries: countries,
|
||||
app_type: document.getElementById('appType').value,
|
||||
app_variant: document.getElementById('appVariant').value,
|
||||
aggregate: document.getElementById('aggregate').checked,
|
||||
use_cache: useCacheCheckbox ? useCacheCheckbox.checked : true
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user