fix: exclude trashed notes from search results and autocomplete
Trashed notes were appearing in search (Cmd+F), Quick Open (Ctrl+P), wikilink autocomplete ([[), and person mention autocomplete (@). Rust: add is_file_trashed() to check frontmatter, filter search_vault results. Frontend: filter trashed entries from useNoteSearch, baseItems in both editor views, and mock search_vault handler. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -52,7 +52,7 @@ export function RawEditorView({ content, path, entries, onContentChange, onSave,
|
||||
const typeEntryMap = useMemo(() => buildTypeEntryMap(entries), [entries])
|
||||
|
||||
const baseItems = useMemo(
|
||||
() => deduplicateByPath(entries.map(entry => ({
|
||||
() => deduplicateByPath(entries.filter(e => !e.trashed).map(entry => ({
|
||||
title: entry.title,
|
||||
aliases: [...new Set([entry.filename.replace(/\.md$/, ''), ...entry.aliases])],
|
||||
group: entry.isA || 'Note',
|
||||
|
||||
@@ -62,7 +62,7 @@ export function SingleEditorView({ editor, entries, onNavigateWikilink, onChange
|
||||
const typeEntryMap = useMemo(() => buildTypeEntryMap(entries), [entries])
|
||||
|
||||
const baseItems = useMemo(
|
||||
() => deduplicateByPath(entries.map(entry => ({
|
||||
() => deduplicateByPath(entries.filter(e => !e.trashed).map(entry => ({
|
||||
title: entry.title,
|
||||
aliases: [...new Set([entry.filename.replace(/\.md$/, ''), ...entry.aliases])],
|
||||
group: entry.isA || 'Note',
|
||||
|
||||
@@ -220,6 +220,35 @@ describe('useNoteSearch', () => {
|
||||
expect(result.current.results[0].title).toBe('Refactoring Notes')
|
||||
})
|
||||
|
||||
it('excludes trashed notes from results', () => {
|
||||
const withTrashed: VaultEntry[] = [
|
||||
makeEntry({ path: '/vault/a.md', title: 'Active Note', modifiedAt: 1700000003 }),
|
||||
makeEntry({ path: '/vault/t.md', title: 'Trashed Note', trashed: true, trashedAt: 1700000000, modifiedAt: 1700000002 }),
|
||||
makeEntry({ path: '/vault/b.md', title: 'Another Active', modifiedAt: 1700000001 }),
|
||||
]
|
||||
const { result } = renderHook(() => useNoteSearch(withTrashed, ''))
|
||||
expect(result.current.results.map(r => r.title)).toEqual(['Active Note', 'Another Active'])
|
||||
})
|
||||
|
||||
it('excludes trashed notes from search results by query', () => {
|
||||
const withTrashed: VaultEntry[] = [
|
||||
makeEntry({ path: '/vault/a.md', title: 'Meeting Notes', modifiedAt: 1700000002 }),
|
||||
makeEntry({ path: '/vault/t.md', title: 'Meeting Draft', trashed: true, modifiedAt: 1700000001 }),
|
||||
]
|
||||
const { result } = renderHook(() => useNoteSearch(withTrashed, 'Meeting'))
|
||||
expect(result.current.results).toHaveLength(1)
|
||||
expect(result.current.results[0].title).toBe('Meeting Notes')
|
||||
})
|
||||
|
||||
it('does not exclude archived notes from results', () => {
|
||||
const withArchived: VaultEntry[] = [
|
||||
makeEntry({ path: '/vault/a.md', title: 'Active Note', modifiedAt: 1700000002 }),
|
||||
makeEntry({ path: '/vault/ar.md', title: 'Archived Note', archived: true, modifiedAt: 1700000001 }),
|
||||
]
|
||||
const { result } = renderHook(() => useNoteSearch(withArchived, ''))
|
||||
expect(result.current.results).toHaveLength(2)
|
||||
})
|
||||
|
||||
it('resolves custom type color from Type entries', () => {
|
||||
const withTypes: VaultEntry[] = [
|
||||
makeEntry({ path: '/vault/t/recipe.md', title: 'Recipe', isA: 'Type', color: 'orange', icon: 'cooking-pot' }),
|
||||
|
||||
@@ -32,7 +32,7 @@ export function useNoteSearch(entries: VaultEntry[], query: string, maxResults =
|
||||
const typeEntryMap = useMemo(() => buildTypeEntryMap(entries), [entries])
|
||||
|
||||
const searchableEntries = useMemo(
|
||||
() => entries.filter((e) => !SEARCH_EXCLUDED_TYPES.has(e.isA ?? '')),
|
||||
() => entries.filter((e) => !e.trashed && !SEARCH_EXCLUDED_TYPES.has(e.isA ?? '')),
|
||||
[entries],
|
||||
)
|
||||
|
||||
|
||||
@@ -269,6 +269,7 @@ export const mockHandlers: Record<string, (args: any) => any> = {
|
||||
if (!q) return { results: [], elapsed_ms: 0, query: q, mode: args.mode }
|
||||
const matches = MOCK_ENTRIES
|
||||
.filter(e => {
|
||||
if (e.trashed) return false
|
||||
const content = MOCK_CONTENT[e.path] ?? ''
|
||||
return e.title.toLowerCase().includes(q) || content.toLowerCase().includes(q)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user