3GPPDocFinder / static /script.js
Omar ID EL MOUMEN
Add feature: Keyword search (FINALLY) + debug (frontend only)
33aecf5
raw
history blame
10.1 kB
// DOM elements
const singleModeBtn = document.getElementById('single-mode-btn');
const batchModeBtn = document.getElementById('batch-mode-btn');
const keywordModeBtn = document.getElementById("keyword-mode-btn");
const indexerModeBtn = document.getElementById("indexer-mode-btn")
const singleInput = document.querySelector('.single-input');
const batchInput = document.querySelector('.batch-input');
const keywordSearchInput = document.querySelector(".keyword-input");
const indexerButtons = document.querySelector(".indexer-buttons")
const docIdInput = document.getElementById('doc-id');
const batchIdsInput = document.getElementById('batch-ids');
const keywordInput = document.getElementById("keywords");
const searchBtn = document.getElementById('search-btn');
const batchSearchBtn = document.getElementById('batch-search-btn');
const keywordSearchBtn = document.getElementById("keyword-search-btn");
const loader = document.getElementById('loader');
const resultsContainer = document.getElementById('results-container');
const resultsList = document.getElementById('results-list');
const resultsStats = document.getElementById('results-stats');
const errorMessage = document.getElementById('error-message');
// Search mode toggle
singleModeBtn.addEventListener('click', () => {
singleModeBtn.classList.add('active');
keywordModeBtn.classList.remove("active");
batchModeBtn.classList.remove('active');
indexerModeBtn.classList.remove("active");
singleInput.style.display = 'block';
batchInput.style.display = 'none';
keywordSearchInput.style.display = "none";
indexerButtons.style.display = "none";
});
batchModeBtn.addEventListener('click', () => {
batchModeBtn.classList.add('active');
keywordModeBtn.classList.remove("active");
singleModeBtn.classList.remove('active');
indexerModeBtn.classList.remove("active");
batchInput.style.display = 'block';
keywordSearchInput.style.display = "none";
indexerButtons.style.display = "none";
singleInput.style.display = 'none';
});
keywordModeBtn.addEventListener('click', () => {
keywordModeBtn.classList.add("active");
singleModeBtn.classList.remove('active');
batchModeBtn.classList.remove("active");
indexerModeBtn.classList.remove("active");
singleInput.style.display = "none";
batchInput.style.display = "none";
indexerButtons.style.display = "none";
keywordSearchInput.style.display = "block";
})
indexerModeBtn.addEventListener('click', ()=>{
keywordModeBtn.classList.remove("active");
singleModeBtn.classList.remove('active');
batchModeBtn.classList.remove("active");
indexerModeBtn.classList.add("active");
singleInput.style.display = "none";
batchInput.style.display = "none";
indexerButtons.style.display = "block";
keywordSearchInput.style.display = "none";
})
keywordSearchBtn.addEventListener("click", async ()=>{
const keywords = keywordInput.value.trim();
if (!keywords) {
showError("Please enter at least one keyword");
return;
}
showLoader();
hideError();
try{
const response = await fetch("/search-spec", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ keywords })
});
const data = await response.json();
if (response.ok){
displayKeywordResults(data);
} else {
showError('Error processing batch request');
}
} catch (error) {
showError('Error connecting to the server. Please check if the API is running.');
console.error('Error:', error);
} finally {
hideLoader();
}
})
// Single document search
searchBtn.addEventListener('click', async () => {
const docId = docIdInput.value.trim();
if (!docId) {
showError('Please enter a document ID');
return;
}
showLoader();
hideError();
try {
const response = await fetch(`/find`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ doc_id: docId, release: null })
});
const data = await response.json();
if (response.ok) {
displaySingleResult(data);
} else {
displaySingleNotFound(docId, data.detail);
}
} catch (error) {
showError('Error connecting to the server. Please check if the API is running.');
console.error('Error:', error);
} finally {
hideLoader();
}
});
// Batch document search
batchSearchBtn.addEventListener('click', async () => {
const batchText = batchIdsInput.value.trim();
if (!batchText) {
showError('Please enter at least one document ID');
return;
}
const docIds = batchText.split('\n')
.map(id => id.trim())
.filter(id => id !== '');
if (docIds.length === 0) {
showError('Please enter at least one valid document ID');
return;
}
showLoader();
hideError();
try {
const response = await fetch(`/batch`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ doc_ids: docIds })
});
const data = await response.json();
if (response.ok) {
displayBatchResults(data);
} else {
showError('Error processing batch request');
}
} catch (error) {
showError('Error connecting to the server. Please check if the API is running.');
console.error('Error:', error);
} finally {
hideLoader();
}
});
// Display single result
function displaySingleResult(data) {
resultsList.innerHTML = '';
const resultItem = document.createElement('div');
resultItem.className = 'result-item';
resultItem.innerHTML = `
<div class="result-header">
<div class="result-id">${data.doc_id}</div>
<div class="result-status status-found">Found</div>
</div>
<div class="result-url">
<a href="${data.url}" target="_blank">${data.url}</a>
</div>
`;
resultsList.appendChild(resultItem);
resultsStats.textContent = `Found in ${data.search_time.toFixed(2)} seconds`;
resultsContainer.style.display = 'block';
}
// Display single not found result
function displaySingleNotFound(docId, message) {
resultsList.innerHTML = '';
const resultItem = document.createElement('div');
resultItem.className = 'result-item';
resultItem.innerHTML = `
<div class="result-header">
<div class="result-id">${docId}</div>
<div class="result-status status-not-found">Not Found</div>
</div>
<div>${message}</div>
`;
resultsList.appendChild(resultItem);
resultsStats.textContent = 'Document not found';
resultsContainer.style.display = 'block';
}
function displayKeywordResults(data) {
resultsList.innerHTML = '';
data.results.forEach(spec => {
const resultItem = document.createElement("div");
resultItem.className = "result-item"
resultItem.innerHTML = `
<div class="result-header">
<div class="result-id">${spec.id}</div>
<div class="result-status status-found">Found</div>
</div>
<div class="result-url">
<p>Title: ${spec.title}</p>
<p>Type: ${spec.type}</p>
<p>Release: ${spec.release}</p>
<p>Version: ${spec.version}</p>
<p>WG: ${spec.working_group}</p>
</div>
`;
resultsList.appendChild(resultItem);
});
resultsStats.textContent = `Found in ${data.search_time.toFixed(2)} seconds`
resultsContainer.style.display = 'block';
}
// Display batch results
function displayBatchResults(data) {
resultsList.innerHTML = '';
// Found documents
Object.entries(data.results).forEach(([docId, url]) => {
const resultItem = document.createElement('div');
resultItem.className = 'result-item';
resultItem.innerHTML = `
<div class="result-header">
<div class="result-id">${docId}</div>
<div class="result-status status-found">Found</div>
</div>
<div class="result-url">
<a href="${url}" target="_blank">${url}</a>
</div>
`;
resultsList.appendChild(resultItem);
});
// Not found documents
data.missing.forEach(docId => {
const resultItem = document.createElement('div');
resultItem.className = 'result-item';
resultItem.innerHTML = `
<div class="result-header">
<div class="result-id">${docId}</div>
<div class="result-status status-not-found">Not Found</div>
</div>
`;
resultsList.appendChild(resultItem);
});
const foundCount = Object.keys(data.results).length;
const totalCount = foundCount + data.missing.length;
resultsStats.textContent = `Found ${foundCount} of ${totalCount} documents in ${data.search_time.toFixed(2)} seconds`;
resultsContainer.style.display = 'block';
}
// Show loader
function showLoader() {
loader.style.display = 'block';
}
// Hide loader
function hideLoader() {
loader.style.display = 'none';
}
// Show error message
function showError(message) {
errorMessage.textContent = message;
errorMessage.style.display = 'block';
}
// Hide error message
function hideError() {
errorMessage.style.display = 'none';
}
// Enter key event for single search
docIdInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
searchBtn.click();
}
});
keywordInput.addEventListener('keypress', (event)=>{
if (event.key === "Enter"){
keywordSearchBtn.click();
}
})