arjunbhargav212's picture
Upload 63 files
5b14aa2 verified
// DocStrange Document Extraction - Frontend JavaScript
class DocStrangeApp {
constructor() {
this.selectedFile = null;
this.extractionResults = null;
this.initializeApp();
}
async initializeApp() {
await this.loadSystemInfo();
this.initializeEventListeners();
}
async loadSystemInfo() {
try {
const response = await fetch('/api/system-info');
if (response.ok) {
const systemInfo = await response.json();
this.updateProcessingModeOptions(systemInfo);
}
} catch (error) {
console.warn('Could not load system info:', error);
}
}
updateProcessingModeOptions(systemInfo) {
// Processing mode is now handled automatically - cloud by default, GPU if available and selected
// No UI changes needed as processing mode selection has been removed
}
initializeEventListeners() {
// File input change
document.getElementById('fileInput').addEventListener('change', (e) => {
this.handleFileSelect(e.target.files[0]);
});
// Drag and drop events
const uploadArea = document.getElementById('fileUploadArea');
uploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
uploadArea.classList.add('dragover');
});
uploadArea.addEventListener('dragleave', (e) => {
e.preventDefault();
uploadArea.classList.remove('dragover');
});
uploadArea.addEventListener('drop', (e) => {
e.preventDefault();
uploadArea.classList.remove('dragover');
const files = e.dataTransfer.files;
if (files.length > 0) {
this.handleFileSelect(files[0]);
}
});
// Click on upload area to trigger file input
uploadArea.addEventListener('click', () => {
document.getElementById('fileInput').click();
});
// Form submission
document.getElementById('uploadForm').addEventListener('submit', (e) => {
e.preventDefault();
this.handleFormSubmission();
});
// Tab switching
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
this.switchTab(e.target.dataset.tab);
});
});
}
handleFileSelect(file) {
if (!file) return;
// Validate file type
const allowedTypes = [
'.pdf', '.docx', '.doc', '.xlsx', '.xls', '.csv', '.txt',
'.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.ppt', '.pptx',
'.html', '.htm'
];
const fileExtension = '.' + file.name.split('.').pop().toLowerCase();
if (!allowedTypes.includes(fileExtension)) {
this.showError(`Unsupported file type: ${fileExtension}`);
return;
}
// Validate file size (100MB limit)
const maxSize = 100 * 1024 * 1024; // 100MB
if (file.size > maxSize) {
this.showError('File too large. Maximum size is 100MB.');
return;
}
this.selectedFile = file;
this.displayFileInfo(file);
this.enableSubmitButton();
}
displayFileInfo(file) {
const fileInfo = document.getElementById('fileInfo');
const fileName = document.getElementById('fileName');
const fileSize = document.getElementById('fileSize');
const uploadArea = document.getElementById('fileUploadArea');
fileName.textContent = file.name;
fileSize.textContent = this.formatFileSize(file.size);
fileInfo.style.display = 'flex';
// Hide the drag and drop area when file is selected
uploadArea.style.display = 'none';
}
formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
removeFile() {
this.selectedFile = null;
const fileInfo = document.getElementById('fileInfo');
const uploadArea = document.getElementById('fileUploadArea');
fileInfo.style.display = 'none';
// Show the drag and drop area again when file is removed
uploadArea.style.display = 'block';
document.getElementById('fileInput').value = '';
this.disableSubmitButton();
this.hideResults();
}
enableSubmitButton() {
const submitBtn = document.getElementById('submitBtn');
submitBtn.disabled = false;
}
disableSubmitButton() {
const submitBtn = document.getElementById('submitBtn');
submitBtn.disabled = true;
}
async handleFormSubmission() {
if (!this.selectedFile) {
this.showError('Please select a file first.');
return;
}
this.showLoading();
this.hideResults();
try {
const formData = new FormData();
formData.append('file', this.selectedFile);
// Get selected output format
const outputFormat = document.querySelector('input[name="outputFormat"]:checked').value;
formData.append('output_format', outputFormat);
// Use cloud processing mode by default
formData.append('processing_mode', 'cloud');
const response = await fetch('/api/extract', {
method: 'POST',
body: formData
});
const result = await response.json();
if (response.ok && result.success) {
this.displayResults(result);
} else {
const errorMessage = result.error || 'Extraction failed';
// Handle specific GPU errors
if (errorMessage.includes('GPU') && errorMessage.includes('not available')) {
this.showError('GPU mode is not available. Please install PyTorch with CUDA support or use cloud processing.');
} else {
this.showError(errorMessage);
}
}
} catch (error) {
console.error('Error during extraction:', error);
this.showError('Network error. Please try again.');
} finally {
this.hideLoading();
}
}
displayResults(result) {
this.extractionResults = result;
// Update metadata
document.getElementById('fileType').textContent = result.metadata.file_type.toUpperCase();
document.getElementById('pagesProcessed').textContent = `${result.metadata.pages_processed} pages`;
document.getElementById('processingTime').textContent = `${result.metadata.processing_time.toFixed(2)}s`;
// Add processing mode to metadata if available
if (result.metadata.processing_mode) {
const processingModeElement = document.getElementById('processingMode');
if (processingModeElement) {
processingModeElement.textContent = result.metadata.processing_mode.toUpperCase();
}
}
// Display content
this.updatePreviewContent(result.content);
this.updateRawContent(result.content);
// Show results section
document.getElementById('resultsSection').style.display = 'block';
// Scroll to results
document.getElementById('resultsSection').scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
updatePreviewContent(content) {
const previewContent = document.getElementById('previewContent');
// Format content based on output type
const outputFormat = document.querySelector('input[name="outputFormat"]:checked').value;
if (outputFormat === 'json' || outputFormat === 'flat-json') {
try {
const formatted = JSON.stringify(JSON.parse(content), null, 2);
previewContent.innerHTML = `<pre class="json-preview">${this.escapeHtml(formatted)}</pre>`;
} catch (e) {
previewContent.textContent = content;
}
} else if (outputFormat === 'html') {
previewContent.innerHTML = content;
} else {
previewContent.textContent = content;
}
}
updateRawContent(content) {
const rawContent = document.getElementById('rawContent');
rawContent.textContent = content;
}
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
switchTab(tabName) {
// Update tab buttons
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.classList.remove('active');
});
document.querySelector(`[data-tab="${tabName}"]`).classList.add('active');
// Update tab content
document.querySelectorAll('.tab-pane').forEach(pane => {
pane.classList.remove('active');
});
document.getElementById(tabName).classList.add('active');
}
showLoading() {
const submitBtn = document.getElementById('submitBtn');
const btnText = submitBtn.querySelector('.btn-text');
const spinner = submitBtn.querySelector('.spinner');
btnText.textContent = 'Processing...';
spinner.style.display = 'block';
submitBtn.disabled = true;
}
hideLoading() {
const submitBtn = document.getElementById('submitBtn');
const btnText = submitBtn.querySelector('.btn-text');
const spinner = submitBtn.querySelector('.spinner');
btnText.textContent = 'Extract Content';
spinner.style.display = 'none';
submitBtn.disabled = false;
}
showError(message) {
// Create error notification
const notification = document.createElement('div');
notification.className = 'error-notification';
notification.innerHTML = `
<div class="error-content">
<span class="error-icon">⚠️</span>
<span class="error-message">${message}</span>
<button class="error-close" onclick="this.parentElement.parentElement.remove()">×</button>
</div>
`;
// Add styles
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #D02B2B;
color: white;
padding: 16px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
z-index: 1000;
max-width: 400px;
`;
notification.querySelector('.error-content').style.cssText = `
display: flex;
align-items: center;
gap: 12px;
`;
notification.querySelector('.error-close').style.cssText = `
background: none;
border: none;
color: white;
font-size: 20px;
cursor: pointer;
margin-left: auto;
`;
document.body.appendChild(notification);
// Auto-remove after 5 seconds
setTimeout(() => {
if (notification.parentElement) {
notification.remove();
}
}, 5000);
}
hideResults() {
document.getElementById('resultsSection').style.display = 'none';
}
}
// Global functions for HTML onclick handlers
function removeFile() {
if (window.docStrangeApp) {
window.docStrangeApp.removeFile();
}
}
function downloadAsText() {
if (window.docStrangeApp && window.docStrangeApp.extractionResults) {
const content = window.docStrangeApp.extractionResults.content;
const fileName = window.docStrangeApp.selectedFile.name;
const outputFormat = document.querySelector('input[name="outputFormat"]:checked').value;
const extension = outputFormat === 'json' ? 'json' : outputFormat === 'html' ? 'html' : 'txt';
const blob = new Blob([content], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${fileName.split('.')[0]}_extracted.${extension}`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
}
function downloadAsJson() {
if (window.docStrangeApp && window.docStrangeApp.extractionResults) {
const result = {
content: window.docStrangeApp.extractionResults.content,
metadata: window.docStrangeApp.extractionResults.metadata,
original_file: window.docStrangeApp.selectedFile.name
};
const fileName = window.docStrangeApp.selectedFile.name;
const blob = new Blob([JSON.stringify(result, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${fileName.split('.')[0]}_extraction_result.json`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
}
// Initialize app when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
window.docStrangeApp = new DocStrangeApp();
});