From 7957c7c7537d1adeb505010b1e50fbb5b1d3d21f Mon Sep 17 00:00:00 2001 From: Saifeddine ALOUI Date: Mon, 27 Jan 2025 10:23:50 +0100 Subject: [PATCH] split the html and javascript code --- lightrag/api/static/index.html | 353 +----------------- lightrag/api/{webui => }/static/js/graph.js | 0 lightrag/api/static/js/lightrag_api.js | 353 ++++++++++++++++++ .../static/__init__.py | 0 .../static/css/__init__.py | 0 .../static/css/graph.css | 0 .../static/css/lightrag.css | 0 .../static/index.html | 0 .../static/js/__init__.py | 0 .../static/js/lightrag.js | 0 10 files changed, 354 insertions(+), 352 deletions(-) rename lightrag/api/{webui => }/static/js/graph.js (100%) create mode 100644 lightrag/api/static/js/lightrag_api.js rename lightrag/api/{webui => webui_depricated}/static/__init__.py (100%) rename lightrag/api/{webui => webui_depricated}/static/css/__init__.py (100%) rename lightrag/api/{webui => webui_depricated}/static/css/graph.css (100%) rename lightrag/api/{webui => webui_depricated}/static/css/lightrag.css (100%) rename lightrag/api/{webui => webui_depricated}/static/index.html (100%) rename lightrag/api/{webui => webui_depricated}/static/js/__init__.py (100%) rename lightrag/api/{webui => webui_depricated}/static/js/lightrag.js (100%) diff --git a/lightrag/api/static/index.html b/lightrag/api/static/index.html index 56a70ad7..60900c03 100644 --- a/lightrag/api/static/index.html +++ b/lightrag/api/static/index.html @@ -98,358 +98,7 @@ - - // 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 ? { 'Authorization': `Bearer ${state.apiKey}` } : {}) - }; - 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; - } catch (error) { - console.error('Upload error:', error); - } - } - progress.classList.add('hidden'); - }); - - updateIndexedFiles(); - }, - - 'query': () => { - const queryBtn = document.getElementById('queryBtn'); - const queryInput = document.getElementById('queryInput'); - const queryMode = document.getElementById('queryMode'); - const queryResult = document.getElementById('queryResult'); - - 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(''); - }; - diff --git a/lightrag/api/webui/static/js/graph.js b/lightrag/api/static/js/graph.js similarity index 100% rename from lightrag/api/webui/static/js/graph.js rename to lightrag/api/static/js/graph.js diff --git a/lightrag/api/static/js/lightrag_api.js b/lightrag/api/static/js/lightrag_api.js new file mode 100644 index 00000000..67e258b9 --- /dev/null +++ b/lightrag/api/static/js/lightrag_api.js @@ -0,0 +1,353 @@ +// 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 ? { 'Authorization': `Bearer ${state.apiKey}` } : {}) + }; + 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; + } catch (error) { + console.error('Upload error:', error); + } + } + progress.classList.add('hidden'); + }); + + 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(''); +}; \ No newline at end of file diff --git a/lightrag/api/webui/static/__init__.py b/lightrag/api/webui_depricated/static/__init__.py similarity index 100% rename from lightrag/api/webui/static/__init__.py rename to lightrag/api/webui_depricated/static/__init__.py diff --git a/lightrag/api/webui/static/css/__init__.py b/lightrag/api/webui_depricated/static/css/__init__.py similarity index 100% rename from lightrag/api/webui/static/css/__init__.py rename to lightrag/api/webui_depricated/static/css/__init__.py diff --git a/lightrag/api/webui/static/css/graph.css b/lightrag/api/webui_depricated/static/css/graph.css similarity index 100% rename from lightrag/api/webui/static/css/graph.css rename to lightrag/api/webui_depricated/static/css/graph.css diff --git a/lightrag/api/webui/static/css/lightrag.css b/lightrag/api/webui_depricated/static/css/lightrag.css similarity index 100% rename from lightrag/api/webui/static/css/lightrag.css rename to lightrag/api/webui_depricated/static/css/lightrag.css diff --git a/lightrag/api/webui/static/index.html b/lightrag/api/webui_depricated/static/index.html similarity index 100% rename from lightrag/api/webui/static/index.html rename to lightrag/api/webui_depricated/static/index.html diff --git a/lightrag/api/webui/static/js/__init__.py b/lightrag/api/webui_depricated/static/js/__init__.py similarity index 100% rename from lightrag/api/webui/static/js/__init__.py rename to lightrag/api/webui_depricated/static/js/__init__.py diff --git a/lightrag/api/webui/static/js/lightrag.js b/lightrag/api/webui_depricated/static/js/lightrag.js similarity index 100% rename from lightrag/api/webui/static/js/lightrag.js rename to lightrag/api/webui_depricated/static/js/lightrag.js