Commit Graph

36 Commits

Author SHA1 Message Date
Luca Rossi
e9c869075a feat: add tags (multi-select) property type (#133)
* design: add tags property type wireframes

Three frames showing the Tags multi-select property:
- Display state: colored pills with X to remove, + button to add
- Input state: dropdown with vault suggestions, checkmarks for selected
- Color picker: per-tag color selection row with accent palette

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add tags (multi-select) property type

Adds a new 'tags' display mode for array-valued frontmatter properties.
Includes TagPill components with deterministic color assignment,
inline tag editing with autocomplete from vault-wide values, and
automatic detection for common tag key patterns (tags, keywords,
categories, labels).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: SearchPanel test — fire ArrowDown on document not window

---------

Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 12:34:01 +01:00
Test
a18a19166b fix: property panel responsive layout + status dropdown click regression
- StatusDropdown: change anchor element from <div> to <span> to fix
  invalid HTML nesting inside <span> parents. Browsers auto-correct
  <div> inside <span> by ripping the element out, breaking
  anchorRef.parentElement positioning. JSDOM doesn't auto-correct,
  so tests passed but the real app's dropdown failed to position.

- StatusValue: revert shrink-0 back to min-w-0 so the status pill
  can truncate in narrow panels instead of overflowing.

- PropertyRow: add min-w-0 and gap-2 for proper flex overflow,
  wrap property key in truncate span.

- AddPropertyForm: add flex-wrap, reduce input widths, set
  min-w-[60px] on value inputs for narrow panel support.

- InfoRow/TypeSelector/ReadOnlyType: add min-w-0 and gap-2.

- Tests: increase timeout for 3 Radix Select interaction tests
  that are slow in JSDOM.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 10:58:23 +01:00
Test
42b463e07a fix: type selector dropdown shows colored icons per type
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 10:54:37 +01:00
Luca Rossi
177e593e90 fix: use portal-based positioning for property panel dropdowns (#130)
* fix: use portal-based positioning for property panel dropdowns

StatusDropdown and DisplayModeSelector used absolute positioning
within the Inspector's overflow-hidden container, causing dropdowns
to be clipped when the Properties panel is narrow (200-280px).

Both now render via createPortal into document.body with fixed
positioning calculated from the trigger element's bounding rect.
This matches the pattern used by existing Radix UI components
(Select, Popover) in the codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* design: property dropdown narrow panel fix — before/after frames

---------

Co-authored-by: Laputa App <laputa@app.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 19:00:30 +01:00
Laputa App
52b1693f43 fix: property dropdowns adapt to narrow panel width
- Popover and Select components: add collisionPadding=8 as default
- TypeSelector and AddPropertyForm SelectContent: position=popper, side=left
- DateValue and AddDateInput PopoverContent: side=left
Dropdowns now flip direction when hitting viewport edge instead of clipping.
2026-02-27 16:58:10 +01:00
Luca Rossi
3d784ce740 fix: unify status dropdown and make color swatch visible (#128)
Bug 1: Replace plain-text Radix Select in AddStatusInput with the same
StatusDropdown component used for existing status properties. Both now
show colored pills, search, and custom status creation.

Bug 2: Add color swatch dot next to each status option in the dropdown.
Clicking it opens an inline palette of 8 accent colors that persist via
localStorage (leveraging existing setStatusColor infrastructure).

Refactor StatusDropdown to extract useStatusFiltering, useStatusKeyboard
hooks and VaultSection/SuggestedSection/CreateSection sub-components to
keep Code Health above 9.2 threshold.

Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 16:53:31 +01:00
lucaronin
464d143313 fix: apply 3 pending fixes directly to main
- fix: deduplicate search results by note path (was PR #116)
- fix: raise z-index on all overlays to appear above BlockNote editor (was PR #119)
- fix: repair corrupted design-full-layouts.pen (was PR #121)

PRs were blocked by merge conflicts after main advanced; applying directly.
2026-02-27 15:35:19 +01:00
Luca Rossi
49b8e1d817 feat: status color picker — assign persistent color per status value (#120)
Add color dot indicators to each status option in the dropdown. Clicking
the dot opens an inline palette of 8 accent colors (from the design system).
Color assignments persist in localStorage and override the built-in defaults.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-27 14:27:43 +00:00
Luca Rossi
4474e635fd fix: unify type selector dropdown to match add-property style (#123)
The TypeSelector on existing properties used a colored pill with no
border, while the add-property form used a bordered muted-bg control.
Align both to the add-property style: 26px height, visible border,
muted background, 4px radius.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-27 15:27:30 +01:00
Luca Rossi
0ebb5033fa feat: type-aware property value inputs — date picker, boolean toggle, status dropdown (#110)
Property value inputs now adapt to their detected or overridden display mode:
- Date properties show a calendar date picker (inline and add form)
- Boolean properties show a yes/no toggle (handles string "true"/"false")
- Status properties show a dropdown with vault + suggested statuses
- Null/empty values are now routed through display mode instead of defaulting to text

Refactored SmartPropertyValueCell and usePropertyPanelState for code health 10.0.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 11:59:23 +00:00
Luca Rossi
ba9a720c4f fix: remove duplicate type icon in add-property input (#107)
SelectValue already renders the icon from the selected SelectItem,
so the explicit Icon in SelectTrigger caused the type icon to appear twice.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 11:12:58 +00:00
lucaronin
d6d1b87d0c fix: resolve Calendar identifier conflict in DynamicPropertiesPanel
- Rename Calendar import from lucide-react to CalendarIcon2 to avoid
  conflict with Calendar from @/components/ui/calendar
- Add tsc --noEmit and pnpm build steps to CI to catch type/bundler
  errors before tests run (prevents this class of bug from reaching main)
2026-02-27 10:47:24 +01:00
Luca Rossi
81990214af feat: replace custom date picker with shadcn/ui Calendar + Popover (#98)
Replace the native HTML5 date input (hidden <input type="date"> with
showPicker()) with a proper shadcn/ui date picker using Calendar and
Popover components. The new implementation provides:

- Calendar popup with month navigation and keyboard support
- Clear date button in the popover footer
- Calendar icon in the trigger button
- Proper date parsing via parseDateValue helper

Also adds the design file design/date-picker-shadcn.pen with closed
and open state frames.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:17:40 +00:00
Luca Rossi
e3f159a3f4 feat: redesign Add Property as inline horizontal form with type selector (#100)
Replace the vertical grey popup with an inline horizontal form that matches
existing property row styling. Fields: [name] [type dropdown] [value] [✓] [×].
Type dropdown uses icon-left design consistent with the app's Select component.
Includes design file with empty and filled state frames.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 13:31:31 +00:00
Luca Rossi
d6b7343dac feat: status property — Notion-style dropdown with color chips (#97)
* fix: resolve search panel freeze by making search_vault async

The search_vault Tauri command was synchronous (fn, not async fn),
blocking the main thread for 30+ seconds during hybrid/semantic
search on large vaults (9200+ files). This caused the macOS beachball.

Changes:
- Make search_vault async with tokio::spawn_blocking (runs qmd off main thread)
- Cache collection name per vault path (avoid repeated qmd collection list calls)
- Cancel inflight searches and debounce timers when panel closes
- Add regression test for stale result cancellation on panel close

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* design: add status property dropdown wireframes

Three frames: closed pill state, open dropdown with suggested/vault
statuses, and custom status creation flow.

Also bump flaky NoteList 9000-entry test timeout from 15s to 30s.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: replace status text edit with Notion-style dropdown

- Extract STATUS_STYLES to shared statusStyles.ts utility
- New StatusDropdown component: filterable popover with colored pills
- StatusPill reusable component for consistent status chip rendering
- Vault-wide status aggregation from entries prop
- Dropdown shows "From vault" and "Suggested" sections
- Custom status creation via type-and-Enter
- Escape/backdrop click cancels without saving
- Keyboard navigation (ArrowUp/Down + Enter)
- 22 new tests covering dropdown behavior + integration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: cargo fmt

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 12:40:27 +00:00
Luca Rossi
7534b8f20c feat: smart property display — type-aware rendering with display mode override (#83)
* design: add smart property display wireframes

Frames: date picker, boolean toggle, status badge, display mode override dropdown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: smart property display — type-aware rendering with display mode override

- Add property type auto-detection (date, boolean, status, url, text) based on value content and property name
- Date properties (ISO strings) show as friendly format (e.g. "Mar 31, 2026") with native date picker on click
- Boolean properties show as toggle buttons
- Status properties auto-detected from key name or known status values, rendered as colored badges
- Each property gets a display mode override dropdown (visible on hover) to force a specific display type
- Display mode overrides persist across sessions via localStorage
- Add mock data with date/boolean fields for testing
- 36 new tests covering type detection, date formatting, localStorage persistence, and UI rendering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 00:12:40 +00:00
Luca Rossi
d79b677119 fix: relation chips now show type color instead of default blue (#68)
* fix: relation chips now display correct type color instead of default blue

Root cause: resolveRef matched entries by path/filename only, while
wiki-links used findEntryByTarget (title, filename, aliases). When a
wikilink target used the note title (differing from filename), resolveRef
failed → null type → default blue.

Changes:
- resolveRef now calls findEntryByTarget first (title/alias match)
- Default color for typeless notes changed from blue to neutral grey
- TypeSelector passes custom color key from Type entries
- DynamicPropertiesPanel refactored to reduce cyclomatic complexity

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* design: add before/after visual for relations type color fix

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add task completion summary

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:02:33 +00:00
lucaronin
49704bc76d fix: align Type row padding with other property rows in Properties panel
ReadOnlyType and TypeSelector containers were missing px-1.5, causing the
Type label to sit flush-left while all other property/info rows were
indented 6px.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:01:51 +01:00
lucaronin
f90bb1f701 fix: use consistent 12px text size for property values in Properties panel
Property values (dates, URLs, text) were inheriting the 14px root font
size instead of using the 12px size already applied in InfoRow and other
inspector sections. Standardize all property value and editing input
text to 12px for visual consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:31:40 +01:00
Luca Rossi
d127ece50d Merge pull request #42 from refactoringhq/task/change-note-type
feat: editable type picker in Properties panel
2026-02-24 15:00:50 +01:00
lucaronin
7219c0799f feat: make URL properties clickable with hover underline
- Add UrlValue component: click opens in browser, pencil icon for edit
- URL detection via isUrlValue() (http/https URLs + bare domains)
- URL normalization: prepends https:// to bare domains
- Malformed URLs silently ignored (no open attempt)
- Long URLs truncated visually but full URL opens on click
- Edit mode via pencil icon or keyboard (Enter/Escape/blur)
- 22 new tests covering detection, normalization, and component behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:46:18 +01:00
lucaronin
5d833b4203 feat: replace read-only Type field with editable dropdown selector
The Type field in the Properties panel was read-only. Now it uses a
Radix Select dropdown that lists all vault types (entries where
isA === "Type"), plus a "None" option to clear the type. Wired to
the existing onUpdateProperty('type', ...) flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:00:34 +01:00
lucaronin
cdd33cf41f fix: exclude YAML frontmatter from word count in Inspector panel
The DynamicPropertiesPanel had a local countWords that used a regex
(/^---[\s\S]*?---/) which could match dashes inside frontmatter values,
leaving part of the frontmatter in the body and inflating the count.

Replace with the canonical countWords from utils/wikilinks.ts which uses
splitFrontmatter (line-based indexOf) and correctly finds the closing
delimiter on its own line.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 12:46:21 +01:00
lucaronin
c8e87f0ab9 feat: replace 'Is a' / 'is_a' with 'type' as the canonical frontmatter key
- Rust Frontmatter struct now parses both 'type' (new) and 'Is A'/'is_a' (legacy),
  with 'type' taking precedence via resolve_type()
- Added migrate_is_a_to_type() vault-wide migration (runs on startup, also exposed as Tauri command)
- Frontend: buildNoteContent and resolveNewType now emit 'type:' in YAML
- Inspector SKIP_KEYS hides 'is_a', 'Is A', 'type', 'title' from property list
  (TypeRow already renders the type with its dedicated UI)
- frontmatterToEntryPatch handles both 'type' and legacy 'is_a' keys
- Mock data updated: all YAML content uses 'type:' instead of 'is_a:'/'Is A:'
- Tests updated to expect 'type:' in generated frontmatter

Product decision: internal VaultEntry field stays as `isA` (TS) / `is_a` (Rust)
to minimize blast radius. The user-facing change is the YAML key and inspector.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 20:34:22 +01:00
lucaronin
23ca40c19a fix: hide is_a/Is A from editable properties (already shown as TypeRow)
The is_a frontmatter key was appearing both as the TypeRow badge and
as a regular editable property. Added both 'is_a' and 'Is A' variants
to SKIP_KEYS to prevent duplication (snake_case used in mock data,
space-separated used in real vault YAML).

Added test verifying is_a is skipped when TypeRow is present.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 15:35:50 +01:00
lucaronin
6527db10a2 feat: distinguish editable from read-only properties in inspector
Split the Properties panel into two visually distinct sections:

1. **Properties** (editable): frontmatter properties with interactive
   hover background, cursor pointer, and click-to-edit. Includes Type
   row, Status, Owner, tags, and all user-defined properties.

2. **Info** (read-only): derived metadata shown below a border
   separator with an "Info" header. Uses muted color (--text-muted)
   with no hover states or click interaction. Includes:
   - Modified date
   - Created date (new)
   - Word count
   - File size (new, formatted as B/KB/MB)

Product decisions:
- Info section uses --text-muted for both labels and values (more
  dimmed than the --muted-foreground used by editable labels)
- Editable rows get rounded hover:bg-muted on the full row
- Type row stays at top of Properties as an identity element
- Added Created date and file Size to give more useful metadata

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 15:19:57 +01:00
lucaronin
e5d96f97ec fix: suppress react-refresh/only-export-components for valid patterns
Co-located utility exports (constants, helper functions, variant
definitions) alongside their component files. These don't affect
Fast Refresh behavior in practice — targeted eslint-disable comments
explain each case:

- DynamicPropertiesPanel: containsWikilinks, RELATIONSHIP_KEYS
- NoteList: re-exported sort/filter utilities
- NoteItem: getTypeIcon utility
- SidebarParts: isSelectionActive utility
- TypeCustomizePopover: ICON_OPTIONS, resolveIcon
- badge/button/tabs: shadcn/ui variant export pattern

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 13:11:38 +01:00
lucaronin
5bbd1469e2 fix: resolve TypeScript build errors in refactored code and test mocks
- Remove unused cn import from NoteList.tsx
- Fix SidebarSelection type narrowing in NoteList entity view
- Fix SortableSection onToggle type in Sidebar Omit type
- Fix TypeRow isA prop to accept null
- Align useEntryActions handleUpdateFrontmatter value type
- Add missing trashed/trashedAt/order to test mock VaultEntry objects

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 11:00:07 +01:00
lucaronin
65d1c753ef refactor: improve code health across 6 more files
- DynamicPropertiesPanel.tsx: extract PropertyValueCell, TypeRow, AddPropertyForm (9.06 → 9.68)
- useKeyboardNavigation.ts: extract classifyShortcut and useLatestRef (9.09 → 9.63)
- frontmatter.ts: extract parseScalar, parseInlineArray, isBlockScalar helpers (9.24 → 9.6)
- StatusBar.tsx: extract VaultMenu and VaultMenuItem components (9.23 → 10.0)
- useVaultLoader.ts: extract tauriCall helper and loadVaultData (9.35 → 10.0)
- useNoteActions.ts: extract resolveNewNote, resolveNewType, executeFrontmatterOp (9.22 → 9.38)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 10:55:45 +01:00
lucaronin
d9a406e926 fix: truncate long property values with ellipsis instead of wrapping
Add `truncate` and `min-w-0` Tailwind classes to property value elements
in the properties panel so long text is shown on a single line with
ellipsis. The full value is visible via the title attribute on hover.

Affected elements:
- EditableValue display span (main property values)
- Status pill in DynamicPropertiesPanel
- Type button in DynamicPropertiesPanel

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 19:07:41 +01:00
lucaronin
527a63b3b5 feat: tag-pill UI for array properties in inspector
Replace vertical EditableList with horizontal TagPillList component.
Array property values now render as inline pill chips with hover X
to remove and a + button to add new items.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 16:26:22 +01:00
lucaronin
9a2f7f0370 feat(inspector): make Type property a clickable navigation chip
The Type field in the Inspector's properties panel is now a colored
clickable chip (styled like relationship chips) that navigates to the
type document when clicked. The "Type" key is also excluded from the
relationships panel to avoid duplication.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:49:55 +01:00
lucaronin
6643b8db8f feat: remove duplicate PROPERTIES section heading from Inspector
The panel title already says "Properties" — the section heading was
redundant. Removed from both DynamicPropertiesPanel and EmptyInspector.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 22:47:49 +01:00
lucaronin
f30733932a feat: apply IBM Plex Mono to labels per design spec
Update NoteList group headers (RELATED NOTES, EVENTS, etc.) to use
font-mono-label class with bg-muted background bar per design.

Update Inspector section titles (Properties, Relationships, Backlinks,
History) and property labels (Type, Status, Modified, Words) to use
font-mono-overline class. Update status badge to IBM Plex Mono with
border-radius 16px per design spec.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 19:41:15 +01:00
lucaronin
3939ba1e97 feat: increase Inspector section spacing to 16px with flex gap
Replace individual mb-4 margins with a flex column gap-4 on the
container, ensuring consistent 16px spacing between Inspector sections.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 18:20:26 +01:00
lucaronin
f9d9bdabf7 refactor: decompose Inspector.tsx into EditableValue, DynamicPropertiesPanel, and frontmatter utils 2026-02-17 12:12:32 +01:00