All Properties cleanup, bulk actions, tags, and property search #208

Open
opened 2026-06-01 20:06:40 +00:00 by steve · 0 comments
Owner

All Properties currently exposes nested generated property paths, lacks
vault-wide property maintenance actions, misses some frontmatter tags, and does
not hand off property clicks to Search.

Problem

  • All Properties lists nested array/object paths such as tags[0] and
    prop[0].name instead of only top-level frontmatter keys.
  • Frontmatter tags arrays are not consistently added to the metadata tag
    cache.
  • Missing widgets/icons for tags, arrays, and objects make many properties
    render with unknown icons.
  • All Properties cannot rename, retag, or delete a property across affected
    files.
  • Clicking a property does not open Search for that property, and Search cannot
    parse quoted property field names such as ["note.status"].

Goal

Make All Properties a top-level frontmatter property browser with bulk
maintenance actions, accurate tag handling, shared tag/chip rendering, and a
Search handoff for property queries.

Scope

  • API metadata type inference, tag extraction, and bulk top-level property
    operations.
  • Shared UI tag component.
  • Markdown All Properties UI, context menu, and frontmatter widgets.
  • Bases and Markdown tag renderer reuse.
  • Search command/query parser support for quoted property names.
  • Specs and focused tests for the changed behavior.

Non-goals

  • Removing nested property tracking from MetadataTypeManager; nested paths
    remain needed for File Properties editing and rename behavior.
  • Changing primitive array data semantics from multitext to tags.
  • Adding undo history for bulk property actions beyond the existing file
    persistence model.

Acceptance Criteria

  • All Properties shows exact top-level frontmatter keys only and preserves
    literal dotted keys such as note.status.
  • All Properties does not show generated nested keys such as tags[0],
    prop[0], or prop[0].name.
  • Frontmatter tags/tag arrays and comma strings populate cache.tags for
    tag UI/search.
  • Registered widgets/icons exist for tags, aliases, multitext, array,
    object, and unknown.
  • Primitive arrays render as removable generic pills without changing their type
    from multitext.
  • File frontmatter rows render top-level tags/tag, aliases/alias, and
    primitive-array multitext properties inline instead of expanding them as
    array/object trees.
  • All Properties row context menu supports Rename, Change Property Type, and
    Delete Property across all affected files.
  • Rename edits inline in the selected row with a full-row accent border instead
    of using browser prompts.
  • Delete uses an in-app confirmation dialog instead of a browser default
    confirmation prompt.
  • Object and complex-array rows can expand into nested property rows that show
    child counts and expose matching nested-property actions.
  • Complex-array nested rows aggregate object-child properties across numeric
    indexes instead of rendering [0], [1], or [N] rows.
  • Clicking aggregate array child rows opens Search with normalized nested
    property filters such as ["items.name"].
  • Bulk delete asks for confirmation with affected file count.
  • Bulk type changes persist the declaration and coerce existing values through
    normalizeMetadataValue() where possible.
  • Bulk actions report progress through app notifications/status progress and
    summarize partial failures.
  • Clicking an All Properties row opens Search with a quoted property query.
  • Search treats [tags] and ["tags"] as equivalent property queries.
  • Search supports quoted nested property filters such as ["property.name"]
    across both object values and arrays of objects while preserving exact dotted
    top-level key matching.

Implementation Notes

  • Build All Properties rows from exact keys in cached top-level frontmatter
    objects, then merge type/count details from metadata type state.
  • Add exact-key bulk APIs to MetadataTypeManager for top-level rename,
    delete, and type changes; do not use lodash path semantics for these
    All Properties actions.
  • Use app.notifications.withProgress({ location: "status", source: "Markdown" }) for bulk work.
  • Move the duplicated Bases/Markdown tag pill into @lapis-notes/ui/tag.
  • Extend the search Lezer grammar to accept Phrase inside PropertyName and
    strip quotes during AST lowering.
  • Use generic editable frontmatter pills for tags, aliases, and primitive arrays;
    do not force a rendered # prefix in the editor, and autocomplete inputs from
    existing values for the same property.
  • Drive the file frontmatter tree/inline decision from resolved property type
    and value complexity so semantic tag and primitive-array widgets get rendered
    before array child derivation can force the tree branch.

Suggested Files or Specs To Inspect

  • packages/api/src/lib/cache.svelte.ts
  • packages/api/src/lib/metadata.svelte.ts
  • packages/api/src/lib/metadata-value.ts
  • packages/api/src/lib/search-query/search-query.grammar
  • packages/plugins/plugin-markdown/src/lib/views/all-properties/all-properties.svelte
  • packages/plugins/plugin-markdown/src/lib/components/frontmatter/widgets.ts
  • packages/plugins/plugin-search/src/search-plugin.ts
  • packages/plugins/plugin-bases/src/bases-view/components/Tag.svelte
  • spec/src/20-packages/plugins/markdown/index.md
  • spec/src/20-packages/plugins/search/index.md
  • spec/src/30-cross-package-contracts/storage-metadata-search.md

Validation Commands

  • pnpm --filter @lapis-notes/api generate:search-query-parser
  • pnpm --filter @lapis-notes/api test:run src/lib/__tests__/metadata-value.test.ts src/lib/__tests__/metadata-type-manager.test.ts src/lib/__tests__/search-query.test.ts src/lib/__tests__/app-database.test.ts
  • pnpm --filter @lapis-notes/api check:all
  • pnpm --filter @lapis-notes/ui check:all
  • pnpm --filter @lapis-notes/markdown check:all
  • pnpm --filter @lapis-notes/search check:all
  • pnpm --filter @lapis-notes/bases check:all
  • make spec-lint
  • mdbook build spec
  • pnpm test:smoke

Follow-up Tasks

Implementation Summary

Populate when closing the issue.

All Properties currently exposes nested generated property paths, lacks vault-wide property maintenance actions, misses some frontmatter tags, and does not hand off property clicks to Search. ## Problem - All Properties lists nested array/object paths such as `tags[0]` and `prop[0].name` instead of only top-level frontmatter keys. - Frontmatter `tags` arrays are not consistently added to the metadata tag cache. - Missing widgets/icons for tags, arrays, and objects make many properties render with unknown icons. - All Properties cannot rename, retag, or delete a property across affected files. - Clicking a property does not open Search for that property, and Search cannot parse quoted property field names such as `["note.status"]`. ## Goal Make All Properties a top-level frontmatter property browser with bulk maintenance actions, accurate tag handling, shared tag/chip rendering, and a Search handoff for property queries. ## Scope - API metadata type inference, tag extraction, and bulk top-level property operations. - Shared UI tag component. - Markdown All Properties UI, context menu, and frontmatter widgets. - Bases and Markdown tag renderer reuse. - Search command/query parser support for quoted property names. - Specs and focused tests for the changed behavior. ## Non-goals - Removing nested property tracking from `MetadataTypeManager`; nested paths remain needed for File Properties editing and rename behavior. - Changing primitive array data semantics from `multitext` to `tags`. - Adding undo history for bulk property actions beyond the existing file persistence model. ## Acceptance Criteria - All Properties shows exact top-level frontmatter keys only and preserves literal dotted keys such as `note.status`. - All Properties does not show generated nested keys such as `tags[0]`, `prop[0]`, or `prop[0].name`. - Frontmatter `tags`/`tag` arrays and comma strings populate `cache.tags` for tag UI/search. - Registered widgets/icons exist for `tags`, `aliases`, `multitext`, `array`, `object`, and `unknown`. - Primitive arrays render as removable generic pills without changing their type from `multitext`. - File frontmatter rows render top-level `tags`/`tag`, `aliases`/`alias`, and primitive-array `multitext` properties inline instead of expanding them as array/object trees. - All Properties row context menu supports Rename, Change Property Type, and Delete Property across all affected files. - Rename edits inline in the selected row with a full-row accent border instead of using browser prompts. - Delete uses an in-app confirmation dialog instead of a browser default confirmation prompt. - Object and complex-array rows can expand into nested property rows that show child counts and expose matching nested-property actions. - Complex-array nested rows aggregate object-child properties across numeric indexes instead of rendering `[0]`, `[1]`, or `[N]` rows. - Clicking aggregate array child rows opens Search with normalized nested property filters such as `["items.name"]`. - Bulk delete asks for confirmation with affected file count. - Bulk type changes persist the declaration and coerce existing values through `normalizeMetadataValue()` where possible. - Bulk actions report progress through app notifications/status progress and summarize partial failures. - Clicking an All Properties row opens Search with a quoted property query. - Search treats `[tags]` and `["tags"]` as equivalent property queries. - Search supports quoted nested property filters such as `["property.name"]` across both object values and arrays of objects while preserving exact dotted top-level key matching. ## Implementation Notes - Build All Properties rows from exact keys in cached top-level frontmatter objects, then merge type/count details from metadata type state. - Add exact-key bulk APIs to `MetadataTypeManager` for top-level rename, delete, and type changes; do not use lodash path semantics for these All Properties actions. - Use `app.notifications.withProgress({ location: "status", source: "Markdown" })` for bulk work. - Move the duplicated Bases/Markdown tag pill into `@lapis-notes/ui/tag`. - Extend the search Lezer grammar to accept `Phrase` inside `PropertyName` and strip quotes during AST lowering. - Use generic editable frontmatter pills for tags, aliases, and primitive arrays; do not force a rendered `#` prefix in the editor, and autocomplete inputs from existing values for the same property. - Drive the file frontmatter tree/inline decision from resolved property type and value complexity so semantic tag and primitive-array widgets get rendered before array child derivation can force the tree branch. ## Suggested Files or Specs To Inspect - `packages/api/src/lib/cache.svelte.ts` - `packages/api/src/lib/metadata.svelte.ts` - `packages/api/src/lib/metadata-value.ts` - `packages/api/src/lib/search-query/search-query.grammar` - `packages/plugins/plugin-markdown/src/lib/views/all-properties/all-properties.svelte` - `packages/plugins/plugin-markdown/src/lib/components/frontmatter/widgets.ts` - `packages/plugins/plugin-search/src/search-plugin.ts` - `packages/plugins/plugin-bases/src/bases-view/components/Tag.svelte` - `spec/src/20-packages/plugins/markdown/index.md` - `spec/src/20-packages/plugins/search/index.md` - `spec/src/30-cross-package-contracts/storage-metadata-search.md` ## Validation Commands - `pnpm --filter @lapis-notes/api generate:search-query-parser` - `pnpm --filter @lapis-notes/api test:run src/lib/__tests__/metadata-value.test.ts src/lib/__tests__/metadata-type-manager.test.ts src/lib/__tests__/search-query.test.ts src/lib/__tests__/app-database.test.ts` - `pnpm --filter @lapis-notes/api check:all` - `pnpm --filter @lapis-notes/ui check:all` - `pnpm --filter @lapis-notes/markdown check:all` - `pnpm --filter @lapis-notes/search check:all` - `pnpm --filter @lapis-notes/bases check:all` - `make spec-lint` - `mdbook build spec` - `pnpm test:smoke` ## Related Issues ## Follow-up Tasks ## Implementation Summary Populate when closing the issue. <!-- backlog:task_id=TASK-MARKDOWN-ALL-PROPERTIES-BULK-ACTIONS source_spec=spec/src/20-packages/plugins/markdown/index.md -->
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lapis-notes/lapis#208
No description provided.