feat(Index.tsx): add functionality to include tags in search queries and persist setting
This commit is contained in:
@@ -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">
|
||||
|
Reference in New Issue
Block a user