// State management const state = { apiKey: localStorage.getItem('apiKey') || '', files: [], indexedFiles: [], currentPage: 'file-manager' }; // Utility functions const showToast = (message, duration = 3000) => { const toast = document.getElementById('toast'); toast.querySelector('div').textContent = message; toast.classList.remove('hidden'); setTimeout(() => toast.classList.add('hidden'), duration); }; const fetchWithAuth = async (url, options = {}) => { const headers = { ...(options.headers || {}), ...(state.apiKey ? { 'X-API-Key': state.apiKey } : {}) // Use X-API-Key instead of Bearer }; return fetch(url, { ...options, headers }); }; // Page renderers const pages = { 'file-manager': () => `

File Manager

Selected Files

Indexed Files

`, 'query': () => `

Query Database

`, 'knowledge-graph': () => `

Under Construction

Knowledge graph visualization will be available in a future update.

`, 'status': () => `

System Status

System Health

Configuration

`, 'settings': () => `

Settings

` }; // Page handlers const handlers = { 'file-manager': () => { const fileInput = document.getElementById('fileInput'); const dropZone = fileInput.parentElement.parentElement; const fileList = document.querySelector('#fileList div'); const indexedFiles = document.querySelector('#indexedFiles div'); const uploadBtn = document.getElementById('uploadBtn'); const updateFileList = () => { fileList.innerHTML = state.files.map(file => `
${file.name}
`).join(''); }; const updateIndexedFiles = async () => { const response = await fetchWithAuth('/health'); const data = await response.json(); indexedFiles.innerHTML = data.indexed_files.map(file => `
${file}
`).join(''); }; dropZone.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.classList.add('border-blue-500'); }); dropZone.addEventListener('dragleave', () => { dropZone.classList.remove('border-blue-500'); }); dropZone.addEventListener('drop', (e) => { e.preventDefault(); dropZone.classList.remove('border-blue-500'); const files = Array.from(e.dataTransfer.files); state.files.push(...files); updateFileList(); }); fileInput.addEventListener('change', () => { state.files.push(...Array.from(fileInput.files)); updateFileList(); }); uploadBtn.addEventListener('click', async () => { if (state.files.length === 0) { showToast('Please select files to upload'); return; } let apiKey = localStorage.getItem('apiKey') || ''; const progress = document.getElementById('uploadProgress'); const progressBar = progress.querySelector('div'); const statusText = document.getElementById('uploadStatus'); progress.classList.remove('hidden'); for (let i = 0; i < state.files.length; i++) { const formData = new FormData(); formData.append('file', state.files[i]); try { await fetch('/documents/upload', { method: 'POST', headers: apiKey ? { 'Authorization': `Bearer ${apiKey}` } : {}, body: formData }); const percentage = ((i + 1) / state.files.length) * 100; progressBar.style.width = `${percentage}%`; statusText.textContent = `${i + 1}/${state.files.length}`; } catch (error) { console.error('Upload error:', error); } } progress.classList.add('hidden'); }); rescanBtn.addEventListener('click', async () => { const progress = document.getElementById('uploadProgress'); const progressBar = progress.querySelector('div'); const statusText = document.getElementById('uploadStatus'); progress.classList.remove('hidden'); try { // Start the scanning process const scanResponse = await fetch('/documents/scan', { method: 'POST', }); if (!scanResponse.ok) { throw new Error('Scan failed to start'); } // Start polling for progress const pollInterval = setInterval(async () => { const progressResponse = await fetch('/documents/scan-progress'); const progressData = await progressResponse.json(); // Update progress bar progressBar.style.width = `${progressData.progress}%`; // Update status text if (progressData.total_files > 0) { statusText.textContent = `Processing ${progressData.current_file} (${progressData.indexed_count}/${progressData.total_files})`; } // Check if scanning is complete if (!progressData.is_scanning) { clearInterval(pollInterval); progress.classList.add('hidden'); statusText.textContent = 'Scan complete!'; } }, 1000); // Poll every second } catch (error) { console.error('Upload error:', error); progress.classList.add('hidden'); statusText.textContent = 'Error during scanning process'; } }); updateIndexedFiles(); }, 'query': () => { const queryBtn = document.getElementById('queryBtn'); const queryInput = document.getElementById('queryInput'); const queryMode = document.getElementById('queryMode'); const queryResult = document.getElementById('queryResult'); let apiKey = localStorage.getItem('apiKey') || ''; queryBtn.addEventListener('click', async () => { const query = queryInput.value.trim(); if (!query) { showToast('Please enter a query'); return; } queryBtn.disabled = true; queryBtn.innerHTML = ` Processing... `; try { const response = await fetchWithAuth('/query', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query, mode: queryMode.value, stream: false, only_need_context: false }) }); const data = await response.json(); queryResult.innerHTML = marked.parse(data.response); } catch (error) { showToast('Error processing query'); } finally { queryBtn.disabled = false; queryBtn.textContent = 'Send Query'; } }); }, 'status': async () => { const healthStatus = document.getElementById('healthStatus'); const configStatus = document.getElementById('configStatus'); try { const response = await fetchWithAuth('/health'); const data = await response.json(); healthStatus.innerHTML = `
${data.status}

Working Directory: ${data.working_directory}

Input Directory: ${data.input_directory}

Indexed Files: ${data.indexed_files_count}

`; configStatus.innerHTML = Object.entries(data.configuration) .map(([key, value]) => `
${key}: ${value}
`).join(''); } catch (error) { showToast('Error fetching status'); } }, 'settings': () => { const saveBtn = document.getElementById('saveSettings'); const apiKeyInput = document.getElementById('apiKeyInput'); saveBtn.addEventListener('click', () => { state.apiKey = apiKeyInput.value; localStorage.setItem('apiKey', state.apiKey); showToast('Settings saved successfully'); }); } }; // Navigation handling document.querySelectorAll('.nav-item').forEach(item => { item.addEventListener('click', (e) => { e.preventDefault(); const page = item.dataset.page; document.getElementById('content').innerHTML = pages[page](); if (handlers[page]) handlers[page](); state.currentPage = page; }); }); // Initialize with file manager document.getElementById('content').innerHTML = pages['file-manager'](); handlers['file-manager'](); // Global functions window.removeFile = (fileName) => { state.files = state.files.filter(file => file.name !== fileName); document.querySelector('#fileList div').innerHTML = state.files.map(file => `
${file.name}
`).join(''); };