feat(Index.tsx): add functionality to include tags in search queries and persist setting

This commit is contained in:
2025-08-29 11:15:06 +02:00
parent d20302c06b
commit 95f99f6ff1

View File

@@ -238,22 +238,40 @@ Keep tags concise, use lowercase, and separate words with hyphens if needed.`);
// Check Ollama status
const checkOllamaStatus = async () => {
try {
// Add timeout to prevent hanging
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 500);
const response = await fetch(`${OLLAMA_ENDPOINT}/api/tags`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
signal: controller.signal,
});
clearTimeout(timeoutId);
if (response.ok) {
setOllamaStatus('online');
addDebugInfo('Ollama connection successful');
return true;
} else {
setOllamaStatus('offline');
addDebugInfo(`Ollama responded with status: ${response.status}`);
return false;
}
} catch (error) {
setOllamaStatus('offline');
if (error instanceof Error) {
if (error.name === 'AbortError') {
addDebugInfo('Ollama connection timed out after 5 seconds');
} else if (error.message.includes('fetch')) {
addDebugInfo('Ollama network error - check if Ollama is running and accessible');
} else {
addDebugInfo(`Ollama connection error: ${error.message}`);
}
}
return false;
}
};
@@ -845,6 +863,7 @@ ${content}${context}`;
q: query,
matchingStrategy: 'all',
limit: 50,
attributesToSearchOn: includeTagsInSearch ? ['content', 'tags'] : ['content'],
attributesToHighlight: includeTagsInSearch ? ['content', 'tags'] : ['content'],
showRankingScore: true,
highlightPreTag: '<mark class="bg-yellow-200">',
@@ -896,7 +915,7 @@ ${content}${context}`;
clearTimeout(searchTimeoutRef.current);
}
};
}, [searchQuery]);
}, [searchQuery, includeTagsInSearch]);
// Go to closest note by ISO8601 date
const goToClosestNoteToDate = async (iso8601: string) => {
@@ -1522,8 +1541,17 @@ ${content}${context}`;
await loadAutoGenerateTagsSetting();
await loadSystemPromptSetting();
await loadContextSizeSetting();
await loadIncludeTagsSetting();
await checkOllamaStatus();
// Retry Ollama connection after a delay if it failed
setTimeout(async () => {
if (ollamaStatus === 'offline') {
addDebugInfo('Retrying Ollama connection...');
await checkOllamaStatus();
}
}, 2000);
const totalTime = Date.now() - dataLoadStartTime;
debugTiming('Total Data Loading', dataLoadStartTime);
addDebugInfo(`Total Data Loading: ${totalTime}ms`);
@@ -1659,6 +1687,33 @@ ${content}${context}`;
}
};
// Load include tags in search setting
const loadIncludeTagsSetting = async () => {
try {
const response = await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes/${SETTINGS_INDEX}/search`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${MEILISEARCH_API_KEY}`,
},
body: JSON.stringify({
q: 'includeTagsInSearch',
filter: 'key = "includeTagsInSearch"',
limit: 1,
}),
}, 'Load Include Tags Setting');
if (response.ok) {
const data = await response.json();
if (data.hits.length > 0) {
setIncludeTagsInSearch(data.hits[0].value === 'true');
}
}
} catch (error) {
console.error('Error loading include tags setting:', error);
}
};
// Save font size setting
const saveFontSizeSetting = async (newFontSize: string) => {
try {
@@ -1807,6 +1862,43 @@ ${content}${context}`;
}
};
// Save include tags in search setting
const saveIncludeTagsSetting = async (enabled: boolean) => {
try {
const document = {
key: 'includeTagsInSearch',
value: enabled.toString(),
updatedAt: new Date().getTime(),
};
const response = await fetchWithTiming(`${MEILISEARCH_ENDPOINT}/indexes/${SETTINGS_INDEX}/documents`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${MEILISEARCH_API_KEY}`,
},
body: JSON.stringify(document),
}, 'Save Include Tags Setting');
if (response.status !== 202) {
throw new Error('Failed to save include tags setting');
}
setIncludeTagsInSearch(enabled);
toast({
title: "Search setting updated",
description: `Tag search ${enabled ? 'enabled' : 'disabled'}.`,
});
} catch (error) {
console.error('Error saving include tags setting:', error);
toast({
title: "Error",
description: "Failed to save include tags setting.",
variant: "destructive",
});
}
};
return (
<div className={`min-h-screen bg-background text-foreground flex flex-col ${getTextClass('base')}`}>
{/* Header */}
@@ -2066,7 +2158,10 @@ ${content}${context}`;
<span className={`${getTextClass('base')} text-muted-foreground`}>Include tags</span>
<Switch
checked={includeTagsInSearch}
onCheckedChange={setIncludeTagsInSearch}
onCheckedChange={async (enabled) => {
await saveIncludeTagsSetting(enabled);
// The search effect will automatically re-run due to includeTagsInSearch dependency
}}
aria-label="Toggle tag search"
/>
</div>
@@ -2303,24 +2398,7 @@ ${content}${context}`;
</div>
</div>
{/* Search Settings */}
<div className="space-y-6">
<h3 className={`${getTextClass('2xl')} font-semibold`}>Search</h3>
<div className="flex items-center justify-between">
<div>
<label className={`${getTextClass('xl')} font-medium`}>Include Tags in Search</label>
<p className={`${getTextClass('base')} text-muted-foreground`}>
Search both content and tags when enabled
</p>
</div>
<Switch
checked={includeTagsInSearch}
onCheckedChange={setIncludeTagsInSearch}
aria-label="Toggle tag search"
/>
</div>
</div>
{/* Display Settings */}
<div className="space-y-6">