Previously, clicking a suggested property slot (Status, Date, URL) would add
an empty property to frontmatter but fail to open the editor. This was due
to a race condition where:
1. handleSuggestedAdd() called onAddProperty() which is async
2. The useEffect tried to detect when the property appeared in frontmatter
3. But frontmatter updates asynchronously after onAddProperty resolves
4. By the time frontmatter is updated, the useEffect had already run
The fix is to directly set the editing key immediately when clicking a
suggested slot, rather than relying on the useEffect to detect the property
being added. This is more reliable because we know we're adding the property
- we don't need to wait for it to appear in frontmatter.
Replace setTimeout-based editingKey activation with a useEffect that
watches propertyEntries. When the newly added property appears in
propertyEntries (after the async backend write completes), the effect
sets editingKey, ensuring the editor/picker opens regardless of timing.
The old setTimeout(fn, 0) approach raced with the async frontmatter
write — editingKey was set before the property existed in the DOM,
so the editing state had no matching PropertyRow to activate.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
View filters that reference custom properties (e.g. "Trashed", "Priority")
were not reactively updating because contentToEntryPatch and
frontmatterToEntryPatch only synced known fields (type, status, etc.)
to the VaultEntry. Custom frontmatter keys were silently dropped.
Now frontmatterToEntryPatch produces a propertiesPatch for unknown keys,
and contentToEntryPatch includes them in the properties field. This
ensures evaluateView sees up-to-date custom property values when
re-filtering the note list.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Each view in the sidebar now shows a count chip displaying the number of
notes matching its filters, consistent with type section count chips.
Count updates reactively as vault entries change.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wrap fireEvent.keyDown calls in act() and assertions in waitFor() so
React state updates flush before checking side effects.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When CI=true, skip injecting __DEMO_VAULT_PATH__ so the CI runner's
absolute path (/Users/runner/...) is never compiled into the bundle.
The default vault path is resolved at runtime via get_default_vault_path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
gray_matter mis-parses certain YAML patterns common in Notion-imported notes:
- Unquoted colons in list items (`- Bitcoin: Net Unrealized`) become objects
- Hash characters in list items (`- # Heading`) become nulls
These caused serde deserialization of the entire Frontmatter struct to fail,
silently dropping type, _organized, and all other fields (178 affected notes).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>