Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .changeset/6431-param-dialog-close-parity.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
---
'@object-ui/app-shell': patch
---

`app-shell`'s two action runtimes now reset `ActionParamDialog` the same way when it closes
(objectui#6431). `useConsoleActionRuntime` closed with `setParamState({ open: false, params: [] })` —
replacing the whole state object, emptying `params` and dropping `title`, `description` and
`resolve` — while `RecordDetailView`, which mounts a second runtime into the same dialog,
closed with `setParamState(s => ({ ...s, open: false }))`. The console runtime moves onto the
field-preserving shape.

The user-visible effect is in the fade-out. `DialogContent` carries
`duration-200 data-[state=closed]:animate-out`, so Radix keeps the content mounted through
its exit animation and the dialog goes on rendering off `state` for the whole ~200ms. Under
the blanking shape a params form the user had just filled in re-titled itself from the
action's own label to the generic "Action parameters", swapped the action's description for
the generic one, and dropped every param row — an empty, generically-labelled box fading out
where a form had been. The confirm pair converged on the same shape for the same reason in
objectui#6034; this is that ruling re-measured on this dialog rather than inherited, because
`ParamDialogState` carries a form rather than display text and "blank it on close" could have
been deliberate here.

It was not, and nothing else changes for the user. The values a user types are not in
`paramState` at all — they live in `ActionParamDialog`'s own `values` state, which its
`useEffect` reseeds from the param defaults on every `state.open` false→true edge, so a
reopened dialog starts blank under either reset shape. The retained `resolve` is inert: the
dialog settles the promise before it asks for the close, and the open path replaces the whole
state object.
34 changes: 33 additions & 1 deletion packages/app-shell/src/hooks/useConsoleActionRuntime.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -712,8 +712,40 @@ export function useConsoleActionRuntime(opts: ConsoleActionRuntimeOptions): Cons
<ActionConfirmDialog state={confirmState} onOpenChange={(open) => {
if (!open) setConfirmState(s => ({ ...s, open: false }));
}} />
{/*
Close = flip `open` and KEEP every other field (objectui#6431), the same
shape the confirm pair converged on above — and for the same reason,
re-measured on THIS dialog rather than inherited from #6034.

`DialogContent` carries `duration-200 data-[state=closed]:animate-out`,
so Radix holds the content mounted through its exit animation and
`ActionParamDialog` goes on rendering off `state` for the whole
fade-out. The `{ open: false, params: [] }` this replaced dropped
`title`, `description` and `resolve` and emptied `params`, so the
closing dialog re-titled itself to the generic `actionDialog.title`,
swapped the action's description for the generic one, and dropped every
param row — a form the user just filled in blanks out and re-labels
itself while it fades.

This is NOT the params form deliberately dropping stale values: the
user's typed values never lived in `paramState`. They live in the
dialog's own `values` state, which its `useEffect` reseeds from the
param defaults on every `state.open` false→true edge — so a reopen
starts blank under BOTH reset shapes, and nothing a user can observe
beyond the fade-out frame differs between them.

The retained `resolve` is inert, as on the confirm path: the dialog
settles the promise before it asks for the close, and the open path
above replaces the whole state object, so nothing stale survives a
reopen.

`RecordDetailView` mounts a SECOND runtime into this same dialog and
already closed this way; that both runtimes now reset it identically is
pinned by `views/RecordDetailView.paramRuntimeParity-6431.test.tsx`,
which also renders the real dialog across the exit-animation frame.
*/}
<ActionParamDialog state={paramState} onOpenChange={(open) => {
if (!open) setParamState({ open: false, params: [] });
if (!open) setParamState(s => ({ ...s, open: false }));
}} />
<ActionResultDialog
state={resultDialogState}
Expand Down
Loading
Loading