From 875d8177a4ec920f94ce13b37109cba49abc4252 Mon Sep 17 00:00:00 2001 From: lucaronin Date: Sat, 7 Mar 2026 00:20:51 +0100 Subject: [PATCH] fix: add visible key to frontmatterToEntryPatch maps The ENTRY_DELETE_MAP and update map in frontmatterToEntryPatch were missing the 'visible' key. When handleDeleteProperty or handleUpdateFrontmatter was called for 'visible', the in-memory VaultEntry was not updated, causing the sidebar to stay stale even after the file on disk was correctly modified. Co-Authored-By: Claude Opus 4.6 --- src-tauri/src/vault/cache.rs | 59 +++++++++++++++++++++++++++++++ src/hooks/useEntryActions.test.ts | 4 +-- src/hooks/useNoteActions.test.ts | 3 ++ src/hooks/useNoteActions.ts | 3 +- 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src-tauri/src/vault/cache.rs b/src-tauri/src/vault/cache.rs index 0202389f..15fde8ea 100644 --- a/src-tauri/src/vault/cache.rs +++ b/src-tauri/src/vault/cache.rs @@ -646,4 +646,63 @@ mod tests { assert!(titles.contains(&"Default Theme")); assert!(titles.contains(&"Dark Theme")); } + + #[test] + fn test_update_same_commit_visible_removed_from_type_note() { + let dir = TempDir::new().unwrap(); + let vault = dir.path(); + + std::process::Command::new("git") + .args(["init"]) + .current_dir(vault) + .output() + .unwrap(); + std::process::Command::new("git") + .args(["config", "user.email", "test@test.com"]) + .current_dir(vault) + .output() + .unwrap(); + std::process::Command::new("git") + .args(["config", "user.name", "Test"]) + .current_dir(vault) + .output() + .unwrap(); + + // Commit a type note with visible: false + create_test_file( + vault, + "type/topic.md", + "---\ntype: Type\nvisible: false\n---\n# Topic\n", + ); + std::process::Command::new("git") + .args(["add", "."]) + .current_dir(vault) + .output() + .unwrap(); + std::process::Command::new("git") + .args(["commit", "-m", "init"]) + .current_dir(vault) + .output() + .unwrap(); + + // Prime the cache + let entries = scan_vault_cached(vault).unwrap(); + assert_eq!(entries.len(), 1); + assert_eq!(entries[0].visible, Some(false), "visible must be false initially"); + + // User removes visible field (uncommitted edit) + create_test_file( + vault, + "type/topic.md", + "---\ntype: Type\n---\n# Topic\n", + ); + + // Reload — must reflect the removal (visible defaults to None) + let entries2 = scan_vault_cached(vault).unwrap(); + assert_eq!(entries2.len(), 1); + assert_eq!( + entries2[0].visible, None, + "visible must be None after removing the field" + ); + } } diff --git a/src/hooks/useEntryActions.test.ts b/src/hooks/useEntryActions.test.ts index c8141b32..4d9c2e75 100644 --- a/src/hooks/useEntryActions.test.ts +++ b/src/hooks/useEntryActions.test.ts @@ -25,8 +25,8 @@ const makeEntry = (overrides: Partial = {}): VaultEntry => ({ relationships: {}, icon: null, color: null, - order: null, - template: null, sort: null, + order: null, sidebarLabel: null, + template: null, sort: null, view: null, visible: null, outgoingLinks: [], properties: {}, ...overrides, diff --git a/src/hooks/useNoteActions.test.ts b/src/hooks/useNoteActions.test.ts index c7acc6fa..9df6e16e 100644 --- a/src/hooks/useNoteActions.test.ts +++ b/src/hooks/useNoteActions.test.ts @@ -290,6 +290,8 @@ describe('frontmatterToEntryPatch', () => { ['trashed', true, { trashed: true }], ['order', 5, { order: 5 }], ['template', '## Heading\n\n', { template: '## Heading\n\n' }], + ['visible', false, { visible: false }], + ['visible', true, { visible: null }], ] as [string, unknown, Partial][])( 'maps %s update to correct entry field', (key, value, expected) => { @@ -321,6 +323,7 @@ describe('frontmatterToEntryPatch', () => { ['archived', { archived: false }], ['order', { order: null }], ['template', { template: null }], + ['visible', { visible: null }], ] as [string, Partial][])( 'maps delete of %s to null/default', (key, expected) => { diff --git a/src/hooks/useNoteActions.ts b/src/hooks/useNoteActions.ts index 0b580762..63a084d8 100644 --- a/src/hooks/useNoteActions.ts +++ b/src/hooks/useNoteActions.ts @@ -150,7 +150,7 @@ const ENTRY_DELETE_MAP: Record> = { icon: { icon: null }, owner: { owner: null }, cadence: { cadence: null }, aliases: { aliases: [] }, belongs_to: { belongsTo: [] }, related_to: { relatedTo: [] }, archived: { archived: false }, trashed: { trashed: false }, order: { order: null }, - template: { template: null }, sort: { sort: null }, + template: { template: null }, sort: { sort: null }, visible: { visible: null }, } /** Map a frontmatter key+value to the corresponding VaultEntry field(s). */ @@ -170,6 +170,7 @@ export function frontmatterToEntryPatch( template: { template: str }, sort: { sort: str }, view: { view: str }, + visible: { visible: value === false ? false : null }, } return updates[k] ?? {} }