improve search

This commit is contained in:
overcuriousity 2025-07-27 22:32:20 +02:00
parent e94c3a0f47
commit 88938d522d
2 changed files with 40 additions and 5 deletions

View File

@ -261,7 +261,7 @@ const sortedTags = Object.entries(tagFrequency)
} }
function filterTools() { function filterTools() {
const searchTerm = elements.searchInput.value.toLowerCase(); const searchTerm = elements.searchInput.value.trim();
const selectedDomain = elements.domainSelect.value; const selectedDomain = elements.domainSelect.value;
const includeProprietary = elements.proprietaryCheckbox.checked; const includeProprietary = elements.proprietaryCheckbox.checked;
@ -270,26 +270,31 @@ const sortedTags = Object.entries(tagFrequency)
const phases = tool.phases || []; const phases = tool.phases || [];
const tags = tool.tags || []; const tags = tool.tags || [];
// Search filter (keep existing logic)
if (searchTerm && !( if (searchTerm && !(
tool.name.toLowerCase().includes(searchTerm) || tool.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
tool.description.toLowerCase().includes(searchTerm) || tool.description.toLowerCase().includes(searchTerm.toLowerCase()) ||
tags.some(tag => tag.toLowerCase().includes(searchTerm)) tags.some(tag => tag.toLowerCase().includes(searchTerm.toLowerCase()))
)) { )) {
return false; return false;
} }
// Domain filter
if (selectedDomain && !domains.includes(selectedDomain)) { if (selectedDomain && !domains.includes(selectedDomain)) {
return false; return false;
} }
// Phase filter
if (selectedPhase && !phases.includes(selectedPhase)) { if (selectedPhase && !phases.includes(selectedPhase)) {
return false; return false;
} }
// Proprietary filter
if (!includeProprietary && !isMethod(tool) && tool.type !== 'concept' && tool.license === 'Proprietary') { if (!includeProprietary && !isMethod(tool) && tool.type !== 'concept' && tool.license === 'Proprietary') {
return false; return false;
} }
// Tag filter
if (selectedTags.size > 0 && !Array.from(selectedTags).every(tag => tags.includes(tag))) { if (selectedTags.size > 0 && !Array.from(selectedTags).every(tag => tags.includes(tag))) {
return false; return false;
} }
@ -297,9 +302,14 @@ const sortedTags = Object.entries(tagFrequency)
return true; return true;
}); });
// Apply search prioritization if there's a search term
const finalResults = searchTerm && window.prioritizeSearchResults
? window.prioritizeSearchResults(filtered, searchTerm)
: filtered;
updateMatrixHighlighting(); updateMatrixHighlighting();
window.dispatchEvent(new CustomEvent('toolsFiltered', { detail: filtered })); window.dispatchEvent(new CustomEvent('toolsFiltered', { detail: finalResults }));
} }
function handleTagClick(tagItem) { function handleTagClick(tagItem) {

View File

@ -80,6 +80,30 @@ const { title, description = 'ForensicPathways - A comprehensive directory of di
scrollToElement(element, options); scrollToElement(element, options);
} }
// Simple search prioritization - exact tag matches first
function prioritizeSearchResults(tools, searchTerm) {
if (!searchTerm || !searchTerm.trim()) {
return tools;
}
const lowerSearchTerm = searchTerm.toLowerCase().trim();
return tools.sort((a, b) => {
const aTagsLower = (a.tags || []).map(tag => tag.toLowerCase());
const bTagsLower = (b.tags || []).map(tag => tag.toLowerCase());
const aExactTag = aTagsLower.includes(lowerSearchTerm);
const bExactTag = bTagsLower.includes(lowerSearchTerm);
// If one has exact tag match and other doesn't, prioritize the exact match
if (aExactTag && !bExactTag) return -1;
if (!aExactTag && bExactTag) return 1;
// Otherwise maintain original order (or sort by name as secondary)
return a.name.localeCompare(b.name);
});
}
// Attach to window immediately - BEFORE DOMContentLoaded // Attach to window immediately - BEFORE DOMContentLoaded
(window as any).createToolSlug = createToolSlug; (window as any).createToolSlug = createToolSlug;
(window as any).findToolByIdentifier = findToolByIdentifier; (window as any).findToolByIdentifier = findToolByIdentifier;
@ -87,6 +111,7 @@ const { title, description = 'ForensicPathways - A comprehensive directory of di
(window as any).scrollToElement = scrollToElement; (window as any).scrollToElement = scrollToElement;
(window as any).scrollToElementById = scrollToElementById; (window as any).scrollToElementById = scrollToElementById;
(window as any).scrollToElementBySelector = scrollToElementBySelector; (window as any).scrollToElementBySelector = scrollToElementBySelector;
(window as any).prioritizeSearchResults = prioritizeSearchResults;
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const THEME_KEY = 'dfir-theme'; const THEME_KEY = 'dfir-theme';