fix: restore modifiedFiles/changes-filter support alongside getNoteStatus

The previous commit replaced modifiedFiles with getNoteStatus, but main
had tests for the 'changes filter' view that depend on modifiedFiles.

This commit restores full backward compat:
- Both modifiedFiles and getNoteStatus props are accepted
- getNoteStatus takes precedence when provided (used by App.tsx)
- modifiedFiles automatically derives status='modified' when getNoteStatus
  is not provided (used by tests and legacy callers)
- isChangesView / 'Changes' header / changes filter all restored

NoteItem continues to use noteStatus prop (new | modified | clean),
so both green (new) and orange (modified) dots work correctly.
This commit is contained in:
lucaronin
2026-02-24 16:35:47 +01:00
parent 9a8b2d930a
commit e7e4dccd3f

View File

@@ -1,6 +1,6 @@
import { useState, useMemo, useCallback, memo } from 'react'
import { Virtuoso } from 'react-virtuoso'
import type { VaultEntry, SidebarSelection, NoteStatus } from '../types'
import type { VaultEntry, SidebarSelection, ModifiedFile, NoteStatus } from '../types'
import { Input } from '@/components/ui/input'
import {
MagnifyingGlass, Plus, CaretDown, CaretRight, Warning,
@@ -21,6 +21,7 @@ interface NoteListProps {
selection: SidebarSelection
selectedNote: VaultEntry | null
allContent: Record<string, string>
modifiedFiles?: ModifiedFile[]
getNoteStatus?: (path: string) => NoteStatus
onSelectNote: (entry: VaultEntry) => void
onReplaceActiveTab: (entry: VaultEntry) => void
@@ -250,12 +251,26 @@ function useNoteListData({ entries, selection, allContent, query, listSort, list
const defaultGetNoteStatus = (): NoteStatus => 'clean'
function NoteListInner({ entries, selection, selectedNote, allContent, getNoteStatus = defaultGetNoteStatus, onSelectNote, onReplaceActiveTab, onCreateNote }: NoteListProps) {
function NoteListInner({ entries, selection, selectedNote, allContent, modifiedFiles, getNoteStatus, onSelectNote, onReplaceActiveTab, onCreateNote }: NoteListProps) {
const [search, setSearch] = useState('')
const [searchVisible, setSearchVisible] = useState(false)
const [collapsedGroups, setCollapsedGroups] = useState<Set<string>>(new Set())
const [sortPrefs, setSortPrefs] = useState<Record<string, SortConfig>>(loadSortPreferences)
const modifiedPathSet = useMemo(
() => new Set((modifiedFiles ?? []).map((f) => f.path)),
[modifiedFiles],
)
// Resolve note status: prefer explicit getNoteStatus prop; fall back to modifiedFiles-derived status
const resolvedGetNoteStatus = useMemo<(path: string) => NoteStatus>(() => {
if (getNoteStatus) return getNoteStatus
if (modifiedFiles && modifiedFiles.length > 0) {
return (path: string) => modifiedPathSet.has(path) ? 'modified' : 'clean'
}
return defaultGetNoteStatus
}, [getNoteStatus, modifiedFiles, modifiedPathSet])
const handleSortChange = useCallback((groupLabel: string, option: SortOption, direction: SortDirection) => {
setSortPrefs((prev) => { const next = { ...prev, [groupLabel]: { option, direction } }; saveSortPreferences(next); return next })
}, [])
@@ -276,8 +291,8 @@ function NoteListInner({ entries, selection, selectedNote, allContent, getNoteSt
}, [onSelectNote, onReplaceActiveTab])
const renderItem = useCallback((entry: VaultEntry) => (
<NoteItem key={entry.path} entry={entry} isSelected={selectedNote?.path === entry.path} noteStatus={getNoteStatus(entry.path)} typeEntryMap={typeEntryMap} onClickNote={handleClickNote} />
), [selectedNote?.path, handleClickNote, typeEntryMap, getNoteStatus])
<NoteItem key={entry.path} entry={entry} isSelected={selectedNote?.path === entry.path} noteStatus={resolvedGetNoteStatus(entry.path)} typeEntryMap={typeEntryMap} onClickNote={handleClickNote} />
), [selectedNote?.path, handleClickNote, typeEntryMap, resolvedGetNoteStatus])
return (
<div className="flex flex-col overflow-hidden border-r border-border bg-card text-foreground" style={{ height: '100%' }}>