Skip to content

fix(ux): drill-down feature parity with main tabs#980

Open
cpcloud wants to merge 4 commits intomicasa-dev:mainfrom
cpcloud:worktree-idempotent-whistling-lampson
Open

fix(ux): drill-down feature parity with main tabs#980
cpcloud wants to merge 4 commits intomicasa-dev:mainfrom
cpcloud:worktree-idempotent-whistling-lampson

Conversation

@cpcloud
Copy link
Copy Markdown
Collaborator

@cpcloud cpcloud commented Apr 23, 2026

Summary

  • Shift+A (magic-add) now opens the deferred document form in every document drill-down; the form pre-scopes to the drilled-into entity and the extraction accept step preserves that scope over any LLM-proposed entity.
  • Shift+D (hard-delete) now works in the Appliance > Maintenance drill-down. The gate, dispatch, and prompt label ("Permanently delete this item?") all key on handler FormKind instead of the drill-down-polluted tab.Kind.
  • Soft-delete/restore status messages and Shift+S (settled filter) also switch to FormKind, so behavior follows the entity rather than the parent tab kind.
  • a in Appliance > Maintenance, Project > Quotes, and Vendor > Quotes now pre-populates the parent entity on the add form instead of defaulting to whichever row happens to sort first.
  • Adds a short "Drill-down Tab Kind Inheritance" note to .claude/codebase/patterns.md so future checks reach for FormKind() / Tab.isDocumentTab() instead of tab.Kind == tabX.

@cpcloud cpcloud added bug Something isn't working ux User experience labels Apr 23, 2026
cpcloud added 4 commits April 23, 2026 10:42
Shift+A (magic-add) dispatch checked tab.Kind == tabDocuments, but
drill-down tabs inherit the parent tab's Kind (e.g. tabAppliances for
Appliances > Documents), so the keypress fell through silently. The
"Press o to open" hint had the same anti-pattern.

Route both through Tab.isDocumentTab(), which already consults the
handler's FormKind() and covers both top-level and entity-scoped
document tabs. When invoked inside a drill-down, the quick form is
pre-populated with the parent entity so the created document is
correctly attached, and acceptDeferredExtraction no longer lets the
LLM override a user-chosen scope.

Reproduction

1. Open a house with at least one Appliance and one document.
2. Navigate to Appliances, enter, and drill into Documents for any
   appliance.
3. Press i to enter edit mode, then Shift+A.
4. Before: nothing happens. After: the quick-add form opens,
   pre-scoped to the appliance.
Drill-down tabs inherit the parent's Kind rather than the semantic
entity Kind. Checks like tab.Kind == tabDocuments silently break
parity; go through Tab.isDocumentTab() or the handler's FormKind()
instead. Refresh the verified date.
promptHardDelete and the confirm-prompt dispatch keyed on tab.Kind, so
Shift+D did nothing in the Appliances > Maintenance drill-down (whose
Kind is tabAppliances, inherited from the parent). The same bug affected
the "Permanently delete this item/incident?" label and the soft-delete
status messages.

Route all entity-semantic checks through handlerFormKind(tab), a new
helper that reads tab.Handler.FormKind() and maps cleanly onto
formIncident, formMaintenance, etc. This keeps drill-downs functionally
identical to their parent tabs.

toggleSettledFilter gets the same treatment: drop the blanket
m.inDetail() early-return and gate on FormKind == formProject via
m.effectiveTab() so any future project-scoped drill-down inherits the
filter automatically.

Reproduction

1. Open a house with at least one appliance.
2. Add a maintenance item scoped to that appliance.
3. Drill into Appliances > Maintenance, press i, then d to soft-delete,
   then Shift+D and y.
4. Before: prompt said "incident", and Yes hard-deleted an incident
   (no-op because no IDs matched), leaving the maintenance item intact.
   After: prompt says "item", and Yes permanently deletes the item.
Pressing "a" in Appliance > Maintenance, Project > Quotes, and
Vendor > Quotes used to open the generic add form and default the
parent field to whichever row happened to sort first in its list.
Users had to re-select the entity they just drilled into.

Carry the drill-down context into the add form via a scoped
startAddFn on each handler, backed by new startMaintenanceFormScoped
and startQuoteFormScoped helpers that pre-populate the known parent
when called with a non-empty ID/name.

Reproduction

1. Create two appliances, Decoy and Parent.
2. Drill into Parent > Maintenance.
3. Press i, then a.
4. Before: form's Appliance select defaults to Decoy. After: it
   defaults to Parent.
@cpcloud cpcloud force-pushed the worktree-idempotent-whistling-lampson branch from df8e8d1 to f43be28 Compare April 23, 2026 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ux User experience

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant