| document.addEventListener('DOMContentLoaded', function() { |
| |
| const uploadForm = document.getElementById('uploadForm'); |
| const filenamesTextarea = document.getElementById('filenames'); |
| const uploadBtn = document.getElementById('uploadBtn'); |
| const clearBtn = document.getElementById('clearBtn'); |
| const clearResultsBtn = document.getElementById('clearResultsBtn'); |
| const resultsSection = document.getElementById('resultsSection'); |
| const resultsContent = document.getElementById('resultsContent'); |
| const loadingSection = document.getElementById('loadingSection'); |
| const configBadge = document.getElementById('configBadge'); |
| const healthBadge = document.getElementById('healthBadge'); |
|
|
| |
| init(); |
|
|
| async function init() { |
| await checkConfiguration(); |
| await checkHealth(); |
| setupEventListeners(); |
| setupKeyboardShortcuts(); |
| } |
|
|
| function setupEventListeners() { |
| |
| uploadForm.addEventListener('submit', handleUpload); |
| |
| |
| clearBtn.addEventListener('click', clearForm); |
| clearResultsBtn.addEventListener('click', clearResults); |
| |
| |
| filenamesTextarea.addEventListener('input', autoResizeTextarea); |
| |
| |
| filenamesTextarea.addEventListener('input', validateInput); |
| } |
|
|
| function setupKeyboardShortcuts() { |
| document.addEventListener('keydown', function(e) { |
| |
| if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { |
| e.preventDefault(); |
| if (!uploadBtn.disabled) { |
| handleUpload(e); |
| } |
| } |
| |
| |
| if (e.key === 'Escape') { |
| clearResults(); |
| } |
| }); |
| } |
|
|
| async function handleUpload(e) { |
| e.preventDefault(); |
| |
| const filenames = filenamesTextarea.value.trim(); |
| if (!filenames) { |
| showError('Please enter at least one filename'); |
| return; |
| } |
|
|
| setLoading(true); |
| clearResults(); |
|
|
| try { |
| const formData = new FormData(); |
| formData.append('filenames', filenames); |
|
|
| const response = await fetch('/upload', { |
| method: 'POST', |
| body: formData |
| }); |
|
|
| if (!response.ok) { |
| const errorData = await response.json(); |
| throw new Error(errorData.detail || `HTTP ${response.status}`); |
| } |
|
|
| const data = await response.json(); |
| displayResults(data.results); |
| |
| } catch (error) { |
| console.error('Upload error:', error); |
| showError(`Upload failed: ${error.message}`); |
| } finally { |
| setLoading(false); |
| } |
| } |
|
|
| function displayResults(results) { |
| if (!results) { |
| showError('No results received from server'); |
| return; |
| } |
|
|
| resultsContent.innerHTML = ''; |
| |
| |
| const lines = results.split('\n').filter(line => line.trim()); |
| |
| lines.forEach(line => { |
| const resultDiv = document.createElement('div'); |
| resultDiv.className = 'result-line'; |
| |
| |
| if (line.includes('✅')) { |
| resultDiv.classList.add('result-success'); |
| } else if (line.includes('❌')) { |
| resultDiv.classList.add('result-error'); |
| } else if (line.includes('⏩')) { |
| resultDiv.classList.add('result-info'); |
| } else { |
| resultDiv.classList.add('result-warning'); |
| } |
| |
| resultDiv.textContent = line; |
| resultsContent.appendChild(resultDiv); |
| }); |
|
|
| resultsSection.style.display = 'block'; |
| resultsSection.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); |
| } |
|
|
| function showError(message) { |
| resultsContent.innerHTML = ''; |
| const errorDiv = document.createElement('div'); |
| errorDiv.className = 'result-line result-error'; |
| errorDiv.textContent = `❌ ${message}`; |
| resultsContent.appendChild(errorDiv); |
| resultsSection.style.display = 'block'; |
| } |
|
|
| function setLoading(isLoading) { |
| if (isLoading) { |
| loadingSection.style.display = 'block'; |
| uploadBtn.disabled = true; |
| uploadBtn.querySelector('.btn-text').textContent = 'Processing...'; |
| } else { |
| loadingSection.style.display = 'none'; |
| uploadBtn.disabled = false; |
| uploadBtn.querySelector('.btn-text').textContent = 'Start Upload'; |
| } |
| } |
|
|
| function clearForm() { |
| filenamesTextarea.value = ''; |
| filenamesTextarea.style.height = 'auto'; |
| validateInput(); |
| filenamesTextarea.focus(); |
| } |
|
|
| function clearResults() { |
| resultsSection.style.display = 'none'; |
| resultsContent.innerHTML = ''; |
| } |
|
|
| function autoResizeTextarea() { |
| filenamesTextarea.style.height = 'auto'; |
| filenamesTextarea.style.height = filenamesTextarea.scrollHeight + 'px'; |
| } |
|
|
| function validateInput() { |
| const value = filenamesTextarea.value.trim(); |
| uploadBtn.disabled = !value; |
| |
| if (value) { |
| uploadBtn.classList.remove('btn-disabled'); |
| } else { |
| uploadBtn.classList.add('btn-disabled'); |
| } |
| } |
|
|
| async function checkConfiguration() { |
| try { |
| const response = await fetch('/config'); |
| const config = await response.json(); |
| |
| const allConfigured = Object.values(config).every(status => status.includes('✅')); |
| |
| if (allConfigured) { |
| configBadge.textContent = 'Ready'; |
| configBadge.className = 'status-badge success'; |
| } else { |
| configBadge.textContent = 'Incomplete'; |
| configBadge.className = 'status-badge warning'; |
| } |
| } catch (error) { |
| console.error('Config check failed:', error); |
| configBadge.textContent = 'Error'; |
| configBadge.className = 'status-badge error'; |
| } |
| } |
|
|
| async function checkHealth() { |
| try { |
| const response = await fetch('/health'); |
| const health = await response.json(); |
| |
| if (health.status === 'healthy') { |
| healthBadge.textContent = 'Healthy'; |
| healthBadge.className = 'status-badge success'; |
| } else { |
| healthBadge.textContent = 'Issues'; |
| healthBadge.className = 'status-badge warning'; |
| } |
| } catch (error) { |
| console.error('Health check failed:', error); |
| healthBadge.textContent = 'Error'; |
| healthBadge.className = 'status-badge error'; |
| } |
| } |
|
|
| |
| setInterval(() => { |
| checkConfiguration(); |
| checkHealth(); |
| }, 30000); |
|
|
| |
| if (!localStorage.getItem('keyboardHintShown')) { |
| setTimeout(() => { |
| showKeyboardHint(); |
| localStorage.setItem('keyboardHintShown', 'true'); |
| }, 2000); |
| } |
|
|
| function showKeyboardHint() { |
| const hint = document.createElement('div'); |
| hint.className = 'keyboard-hint'; |
| hint.innerHTML = '💡 Tip: Use Ctrl+Enter to upload, Esc to clear results'; |
| document.body.appendChild(hint); |
| |
| setTimeout(() => hint.classList.add('show'), 100); |
| setTimeout(() => { |
| hint.classList.remove('show'); |
| setTimeout(() => document.body.removeChild(hint), 300); |
| }, 4000); |
| } |
|
|
| |
| uploadBtn.addEventListener('mouseenter', function() { |
| if (!this.disabled) { |
| this.style.transform = 'translateY(-2px)'; |
| } |
| }); |
|
|
| uploadBtn.addEventListener('mouseleave', function() { |
| this.style.transform = 'translateY(0)'; |
| }); |
|
|
| |
| validateInput(); |
| }); |
|
|
|
|