Show a loading state while a project transfer runs

What does this MR do and why?

Clicking Confirm in the Transfer project modal closed the modal and left the page idle while the transfer ran. A transfer can take tens of seconds, so users reported it feeling stuck or broken and retried. confirm_danger_modal.vue already supports a confirmLoading prop (spinner plus disabled on the primary action); nothing threaded it through.

The fix:

  • confirm_danger.vue (shared wrapper) gains a pass-through confirmLoading prop and forwards the modal's confirm event object to consumers.
  • transfer_project_form.vue owns the transfer flow. It takes targetFormId and targetHiddenInputId props; a watcher writes the selected namespace id to the hidden input, and onConfirm prevents the modal's default close, flips confirmLoading, and calls form.submit() inside a try/catch that resets confirmLoading if the submit throws. The modal stays open with the Confirm button in its loading state until the browser navigates to the transfer result.
  • init_transfer_project_form.js is mount-and-props only: it reads the target form and hidden input ids off the element's dataset and passes them to the component. No logic and no event handling live there.

Consumer audit for the shared wrapper (confirm_danger.vue):

Consumer Effect
projects/settings/components/transfer_project_form.vue The fix; opts in.
init_confirm_danger.js (project/group removal forms) Handler ignores the new event argument; confirmLoading defaults to false. Unchanged.
groups/components/transfer_group_form.vue Re-emits confirm without arguments, as before. Unchanged (the same loading treatment could be threaded through for group transfers as a follow-up).
pages/projects/shared/permissions/components/settings_panel.vue Re-emits confirm without arguments. Unchanged.

No consumer imports confirm_danger_modal.vue directly, and the modal itself is untouched. With the beta groups_and_projects_async_transfer flag enabled, the submit returns quickly and the loading state just bridges the redirect.

References

Related to Transfer project button in modal is clickable while transfer is in progress (#344578).

Screenshots or screen recordings

Screen recordings

Flag state Recording
Off (synchronous transfer)
On (groups_and_projects_async_transfer)

Flag off: Confirm stays in a loading state through the request, then the browser navigates to the transferred project. Flag on: a brief loading bridge, then redirect to the project settings page with an info alert that the transfer is scheduled. Both were captured on a local development instance, so the synchronous window shown is only a couple of seconds. On GitLab.com a transfer can take much longer, which is the window the loading state covers.

View Before After
After clicking Confirm transfer_in_flight transfer_in_flight
Modal region (zoom) transfer_modal_zoom transfer_modal_zoom

State after clicking Confirm with the transfer request in flight. Before: the modal closes and the page gives no sign a transfer is running (the Transfer project button is even enabled again). After: the modal stays open and Confirm shows a spinner, non-interactive (aria-disabled). The zoom row crops the same modal region on both sides; on the before it shows the page beneath because the modal has closed.

How to set up and validate locally

  1. In a project you own, go to Settings > General > Advanced > Transfer project.
  2. Pick a target namespace, click Transfer project, type the confirmation phrase, and click Confirm.
  3. The modal stays open and the Confirm button shows a spinner and is not clickable until the transfer result page loads.
  4. Enable the groups_and_projects_async_transfer feature flag to see the other flow: after Confirm, a brief loading state precedes a redirect to the project settings page with a banner that the transfer is scheduled.

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.

Edited by Paul W

Merge request reports

Loading
Loading