Keep the create branch submit button disabled while validating
What does this MR do and why?
In the work item Create branch / Create merge request modal, typing a branch name and pressing the submit button right away can silently do nothing: the modal stays open, the name is valid, the button is enabled, and no branch is created.
The branch name field validates through a 250ms debounce, and checkingBranchValidity — which drives the submit button's loading (disabled) state — is only set once the debounce fires. During that window the branch name is already stale while the button is still enabled, so a click landing there is dropped: the check starts right after the press, switches the button into its loading state, and the click never reaches the handler.
This MR marks the check as pending synchronously on input, so the button is disabled from the first keystroke until the name has been validated.
A check that is still in flight when a newer one starts closed the same window from the other side: its response released the button while the newer name was unvalidated, and its verdict could overwrite the newer one. The superseded request is now cancelled, and only the newest check releases the button.
The race is also a plausible source of flakiness in spec/features/work_items/issues/user_creates_branch_and_merge_request_spec.rb (the when branch name is custom examples), where the click reliably lands inside that window on a loaded CI machine. On a fork of GitLab running that spec, the three examples failed on nearly every run before this change and pass consistently after it.
References
- Jest coverage added in this MR: 4 examples in
spec/frontend/work_items/components/work_item_development/work_item_create_branch_merge_request_modal_spec.js, covering both sides of the window (pending state on the first keystroke, and a superseded in-flight check resolving while a newer one runs). - Note for reviewers: the default
lodash.debouncemock in the frontend test setup is synchronous and hides this window entirely, so the new block raisesJEST_DEBOUNCE_THROTTLE_TIMEOUTto exercise the real timing.
Screenshots or screen recordings
No visual change: the modal looks the same, only the timing of the submit button's existing loading (disabled) state changes — it now also covers the debounce window.
| Before | After |
|---|---|
| Type a branch name and click Create branch within 250ms: nothing happens, the modal stays open and the branch is not created. | The button is disabled from the first keystroke until the name is validated, so the click cannot be dropped. |
How to set up and validate locally
- Open any issue (work item) in GDK, and in the Development widget choose Create branch.
- In the branch name field, select the suggested name and type a new one, then click Create branch as soon as you finish typing (within 250ms of the last keystroke). To make the window easy to hit, temporarily shorten the debounce in
checkBranchValidityfrom250to e.g.2000. - Before this change: the click is swallowed, the modal stays open, no branch is created. After this change: the button is already disabled/loading, so the click waits for the validation to finish and then creates the branch.
- Jest:
25/25 pass with this change; the two new pending-state examples fail on
yarn jest spec/frontend/work_items/components/work_item_development/work_item_create_branch_merge_request_modal_spec.jsmasterwithout it.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.