fix(bookings): keep user input entered while the booking form initialises - #478
Merged
Merged
Conversation
…ises `newForm` defers itself until the current user has loaded, then re-enters and resets the form. The form is already rendered and interactive by then, so anything typed or toggled in that window was silently destroyed: the title reverted to the default, All Day switched back off, Require locker switched back on. It only bites on a slow load, which is why it reads as the app being unreliable rather than as a reproducible bug. Carry the user's edits across the deferred re-entry and replay them over the incoming booking. Only fields the user actually touched are carried, read from the signal-forms dirty flags, so programmatic writes are ignored and a field left alone still takes its value from the booking being opened. Replayed before `applyDurationSettings`, so a restored `all_day` still drives the time-sync window, and before `_syncWindowIfUnchanged`, which compares against the initial window and so leaves a user-changed one alone of its own accord. Fixes PPT-2643 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Collaborator
|
LGTM |
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.
Fixes PPT-2643.
The bug
BookingFormService.newForm()defers itself until the current user has loaded:The form accepts input during that window. When initialisation completes it resets, silently discarding whatever was entered: title reverts to the default
Booking, All Day switches back off, Require locker switches back on.On a fast connection nobody notices because init finishes first. On a slow one you start typing a title and it vanishes a second later. It affects every flow through this shared service, so desk, locker, parking, visitor and room, across workplace and the other booking UIs.
The fix
Option A from the ticket: preserve the input rather than gate interactivity.
The user's edits are captured on the way back into
newFormand replayed over the incoming booking. Only fields the user actually touched are carried, read from the signal-formsdirtyflags, so programmatic writes (_patch,model.set) are ignored and a field the user never touched still takes its value from the booking being opened.Placement matters and is commented in the source. The replay happens after the main patch but before
applyDurationSettings(), so a restoredall_daystill drives the time-sync window, and before_syncWindowIfUnchanged(), which compares against the initial window and so yields to a user-changed one without any extra handling.The capture is set synchronously immediately before the re-entry, so there is no window in which a normal
newFormcall could consume edits meant for a deferred one.I did not take Option B (gating interactivity behind a loader) because it is a visible UX change across every booking flow and is yours to call.
Testing
Three specs in
booking-form.service.spec.tsunderinitialisation while the user is still loading.No mocking.
currentUserIsLoaded()reports "loaded" whenever it detects a test runtime, so the tests neutralise that runtime probe to reach the deferred branch, which keeps the real promise plumbing incurrentUserLoaded()under test rather than a stub of it.Red-checked against unfixed code, where two of the three fail with exactly the ticket's symptoms:
The third (
does not resurrect that input on the next new form) passes either way by design. It guards against the new code leaking preserved edits into a later form rather than reproducing the original bug.nx test bookings— 393 passednx affected -t test— 25 projects, all passednx affected -t build— 16 projects, all builtnx lintfails in this workspace on untouched libraries too (Failed to load config "plugin:@angular-eslint/recommended"), so it is pre-existing and unrelated.Follow-up
The workplace e2e suite currently works around this bug in
bookDeskViaUIwith a converging retry block, which means it no longer detects it. Once this merges that workaround should come out and be replaced with a spec asserting input survives initialisation. That lives on the e2e branches (#476/#477) and is not touched here.How it was found: the new e2e suite, which produced bookings saved under the wrong title locally and an unopenable confirm dialog in CI (a reverted All Day leaves the default 5-minute slot, which on a slow run has already passed and invalidates the form).
🤖 Generated with Claude Code