fix(web): keep the inline "New quick action" form open on click (BUG-2281)#1005
Merged
Conversation
…2281)
Clicking the QuickActionsMenu footer "+ New quick action" flipped
showCreateForm=true, unmounting the footer's {:else} branch (the very
button clicked). Svelte 5 flushSyncs after a delegated event handler, so
by the time that click bubbled on to the <svelte:window> click-outside
handler the button was detached — target.closest('.quick-actions-menu')
returned null, and handleWindowClick treated it as an outside click and
closed the whole menu, wiping the create form the instant it opened. The
create-form Cancel button had the same detach-then-close quirk (closed
the menu instead of returning to the action list).
handleTriggerClick already guards this with e.stopPropagation();
handleOpenCreateForm and the Cancel handler did not. Add the same guard
to both. Adds a Playwright regression test (mutation-tested: fails on the
pre-fix code, passes after) — the inline form is exercised in a real
Chromium event pipeline for the first time (jsdom doesn't reproduce the
mid-bubble detach, and the capstone spec only asserted the button was
visible, never clicked it).
Also documents BUG-2280 in ItemDetail.svelte: the QuickActionsMenu
oncollectionupdated callback's `{@const keyedSlug = itemSlug}` fence was a
Svelte-5 no-op, but the callback is already switch-safe by two independent
layers (the child-side collection-id guard reads the LIVE parent
collection and drops a cross-collection callback; loadData's identity
clause forces the correct collection regardless). Replaces the dead no-op
fence with a comment explaining why it's safe and warning against
re-adding a no-op snapshot fence (the literal BUG-2129 trap). No
behavior change in ItemDetail.
BUG-2281: real, fixed. BUG-2280: investigated, not a live bug (wontfix).
Claude-Session: https://claude.ai/code/session_01EZ6yr6pAUFb1uffan912ra
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Started as
/pad ultra-codex BUG-2129. BUG-2129 turned out to be already fixed and merged (#961) — the Pad item was just never flipped tofixed(now done, verified green). The mandated independent switch-safety Codex sweep it asked for surfaced two adjacent findings inQuickActionsMenu; this PR ships the one that's real.BUG-2281 (real bug, fixed) — inline "New quick action" form closed instantly
Clicking the QuickActionsMenu footer "+ New quick action" flipped
showCreateForm=true, unmounting the footer's{:else}branch (the very button clicked). Svelte 5flushSyncs after a delegated event handler, so by the time that click bubbled on to the<svelte:window>click-outside handler the button was detached —target.closest('.quick-actions-menu')returned null,handleWindowClicktreated it as an outside click, and the whole menu closed, wiping the create form the instant it opened. The Cancel button had the same quirk (closed the menu instead of returning to the action list).handleTriggerClickalready guards this withe.stopPropagation();handleOpenCreateFormand the Cancel handler didn't. This adds the same guard to both.Regression test (
web/e2e/quickactions-inline-form.spec.ts): mutation-tested — fails on the pre-fix code, passes after. The inline form is exercised in a real Chromium event pipeline for the first time (jsdom doesn't reproduce the mid-bubble detach; the capstone spec only asserted the button was visible, never clicked it).BUG-2280 (investigated, not a live bug — wontfix)
Codex initially flagged the
QuickActionsMenuoncollectionupdatedcallback's{@const keyedSlug = itemSlug}fence as a no-op that lets a cross-collection switch land collection A onto item B. Empirically disproven: the destroyed instance'scollectionprop reads the live parent value (collB), so the existing child-side guard (collection?.id !== baseCollection.id) drops the callback;loadData's identity clause is a second backstop. The dead no-op fence is replaced with a comment documenting why the callback is safe and warning against re-adding a no-op snapshot fence (the literal BUG-2129 trap). No behavior change in ItemDetail.Testing
npm run check(svelte-check): 0 errorsnpm run test(vitest): 464 passedquickactions-inline-form.spec.ts(BUG-2281) +pane-collection-migration-race.spec.ts(BUG-2129 ×2) all green; BUG-2281 mutation-testedhttps://claude.ai/code/session_01EZ6yr6pAUFb1uffan912ra