Skip to content

finding(app-shell): a THIRD ActionParamDialog consumer — MetadataTypeActions still blanks paramState on close #6473

Description

@claude

Found while implementing #6431 (converge the two action runtimes' ActionParamDialog close handlers). Filed unassigned, out of that card's declared file face.

Verified on origin/main @ e929c562a.

There is a THIRD ActionParamDialog consumer, and it still blanks on close

#6431 is written as "app-shell mounts two action runtimes into two copies of ActionParamDialog". There are three. packages/app-shell/src/views/metadata-admin/MetadataTypeActions.tsx holds its own paramState and renders its own copy of the dialog:

openclose
hooks/useConsoleActionRuntime.tsx:264:748 — field-preserving as of #6431
views/RecordDetailView.tsx:562:2519 — field-preserving
views/metadata-admin/MetadataTypeActions.tsx:115setParamState({ open: true, params, title, resolve }):245setParamState({ open: false, params: [] })replaces the whole state

After #6431 lands, this is the only one of the three still on the blanking shape.

Why this was not folded into #6431

#6431's declared file face is the two runtimes it names, and the triage ruling fenced it on "two runtimes disagreeing". This file was neither in the card's premise nor in its file face.

It is also not the same mechanical call, which is why it is a ruling rather than a rename. This close handler settles the promise itself before resetting:

onOpenChange={(open)=>{if(!open){paramState.resolve?.(null);setParamState({open: false,params: []});}}}

ActionParamDialog.handleCancel already calls state.resolve?.(null) before it calls onOpenChange(false), so this is a second settle on an already-settled promise — inert today, but converging this site means deciding whether that line stays, and that decision is not implied by #6431's measurement.

The measured consequence, if it helps triage

The measurement done for #6431 applies unchanged to this surface, since it is the same dialog component. DialogContent carries duration-200 data-[state=closed]:animate-out, so Radix holds the content mounted through the exit animation and the dialog renders off state for the whole fade-out. Under the blanking shape the closing dialog re-titles itself from the action's own label to the generic actionDialog.title, swaps the action's description for the generic one, and drops every param row. MetadataTypeActions passes a real title (:115), so it does have something to lose here.

Not user-data loss: the values a user types live in the dialog's own values state, reseeded from the param defaults on every state.open false→true edge, so a reopen starts blank under either shape.

Related: #6431 (this pair's PR carries the measurement and the pin), #6034 (the confirm pair), #5610, #3320 — the same family of a surface re-implementing a shared runtime and then diverging from it with nothing red in between.


Generated by Claude Code


Generated by Claude Code

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatched

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions