Prefill upstream repositories on virtual repository edit

What does this MR do and why?

This MR is Step 12 of the "monolith/S07 Repository CRUD - virtual repositories" plan. It covers the read half of that step; save wiring follows in a later MR.

It makes these changes to the upstream repositories card in the Artifact Registry create and edit forms:

  1. Prefills the card on the edit page for a virtual repository. The card was empty because the edit form never read the stored upstream list. It now runs the existing get_repository_upstream_repositories GraphQL query for virtual repositories only (hosted and remote kinds skip it), maps the associations into card rows in position order, and holds the whole form behind the loading skeleton until the list arrives. If the read fails, the common fields stay editable and the card shows a non-dismissible alert, "Failed to load upstream repositories." The card gained a loadFailed prop, the shared form passes it through, and a Storybook story for a virtual repository was added. Saving the list is not part of this MR.

  2. Removes the per-source Edit (pencil) button from the card's order table according to discussion. An association's only changeable property is its position, and the reorder arrows and move-to-start / move-to-end menu items already cover that. The button also navigated away from a form with unsaved changes.

  3. Fixes three review follow-ups from the picker MR Add upstream repository picker to the virtual r... (!256875 - merged) • Rahul Chanila • 19.5:

    • The picker no longer hides the search input's placeholder once something is picked, since that overrode default browser behavior for no benefit.
    • The card no longer moves focus by querying the DOM, including the child table's DOM. It now renders its own Add repository button in the crud component's actions slot and focuses it through a ref, focuses its cap message through a ref, and the order table exposes focusRemove(index) and focusArrow(index, direction) backed by per-row refs. Behavior is unchanged.
    • Loading a further page of picker results with fetchMore ignored the returned promise, so a network error on a later page was an unhandled rejection with no alert. It now sets the same error state as a failed first page, so the existing alert renders and the rows already loaded stay listed.

Tests: Jest specs cover the prefill (the read, position order, skipped for other kinds, failed read, in-flight state), the removed button, the placeholder, the two focus methods, and the failed page load. The whole artifact registry frontend spec directory passes.

Everything here is behind the artifact_registry_ui feature flag, which is disabled by default, so there is no changelog entry and no visible effect until the flag is enabled.

References

Screenshots or screen recordings

Edit page (with prefill data) Edit page (API fails)
Screenshot_2026-09-24_at_9.18.21_pm Screenshot_2026-09-24_at_9.18.04_pm

How to set up and validate locally

  1. In a Rails console, enable the feature flag:
    Feature.enable(:artifact_registry_ui)
  2. Use an organization with Artifact Registry enabled and a virtual repository that has upstream repositories.
  3. Open that repository's edit page and confirm the card lists the stored upstreams in order.
  4. Check that the picker keeps its placeholder after a pick.
  5. Check that no pencil button appears on any row.
  6. Close the picker and confirm focus returns to the Add repository button.

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.

🤖 Generated with Claude Code

Edited by Rahul Chanila

Merge request reports

Loading
Loading