Add an empty state to the artifact version list

What does this MR do and why?

This change is behind the feature flag :artifact_registry_ui

Step 23 of monolith/S14. Adds the empty state the artifact version list shows when an artifact has nothing published. Until now a zero-row read fell through to GlTable's default empty text, which is item 4 of #614161 — and the reason that item says the empty-state step and a show-empty fix must not both ship. This closes it.

The state words itself from the format, because the two families do not list the same thing: Maven and npm artifacts hold versions, Docker and OCI artifacts hold manifests.

Its action goes to the repository rather than rendering publish instructions inline. The repository owns that surface and has already merged it, which is also why this state is thinner than its sibling detail/artifacts_empty_state.vue — no tool selector and no snippet blocks.

This MR is stacked. It targets zcuddy-s14-step16-manifests-table (!250140 (merged)), not master. That branch is what first mounts a table region for a container artifact; before it, version_list.vue rendered the heading alone for Docker and OCI, so the manifests wording had no branch to render in or be tested against. Retarget to master once !250140 (merged) merges.

Changes

  • repositories/versions/version_list_empty_state.vue (new) — illustration, format-appropriate heading and support text, and the link to the repository.
  • The action is a router link in GlEmptyState's actions slot rather than its own primary-button-link, which renders an href and would reload the whole SPA. <gl-button :to> is already how this app navigates (see detail/repository_header.vue).
  • repositories/versions/versions_section.vue — a name prop, and one template arm. It sits after the error arm and before both table arms, so a read that failed is never reported as one that came back empty.
  • repositories/versions/version_list.vue — passes the repository name down, and announces the empty result through the existing live region instead of reusing the message meant for a populated one. A screen reader now hears No versions found for <name>. rather than Version list for <name> updated. over an empty table.
  • Specs: version_list_empty_state_spec.js (new), plus the empty arm in versions_section_spec.js and version_list_spec.js. 1158 Jest tests pass on both Vue 2 and Vue 3.
  • Four Storybook stories, one per format, so the state is covered by the automated axe run.

Screenshots or screen recordings

Maven and npm Docker and OCI
maven docker

Both verified in the browser: the heading renders as an h2 under the page's own heading, and the action resolves to the repository route (/o/gitlab-org/-/artifact_registry/acme/repositories/my-repository) as a router link rather than an href.

How to set up and validate locally

The seeded mock generator ladders every artifact with at least two versions, so the empty state is not reachable by URL in the GDK. Drive it from Storybook:

  1. yarn storybook:start
  2. Open ee/artifact_registry/repositories/versions/version_list_empty_state and step through the Maven, Npm, Docker, and Oci stories.
  3. Confirm the Maven and npm stories say versions and the container stories say manifests.
  4. Confirm Go to repository renders as a link to the repository detail path, not to a server URL.

To see it in the page rather than in isolation, open version_list and use the WithoutVersions and WithoutManifests stories, which !250140 added and which previously rendered a headers-only table.

Agent Notes

  • Why this is stacked rather than off master. Every remaining S14 frontend step touches version_list.vue and constants.js, which the four open MRs already claim, and !250140 renames the data layer those steps build on (versionConnectionartifactConnection, versionsrows, readsVersionsreadsManifests). Off master this step would rebase twice and the second rebase would rewrite the very expression its empty arm is built on. It would also only be half-testable, since the container branch is unreachable there.
  • The setup-instructions affordance was a genuine fork. The spec asks for "a link to the repository's setup instructions, which monolith/S05 owns". The alternative was mounting S05's merged SetupDrawer in place, whose public interface (open, name, format, close) !250529 does not change. We chose the router link, reading the parenthetical as the reason it is a link rather than re-rendered content. If you would rather it opened the drawer without leaving the page, that is a small change and the drawer is already reusable.
  • The button says "Go to repository", not "View setup instructions". It navigates; a second click on the repository page opens the drawer. A label promising the instructions directly would not be honest about what the click does. A follow-up could deep-link the drawer open via a route query, but that touches repository_actions.vue, which is S05's file.
  • Not in scope, deliberately. The spec has the container empty state name the Referrer manifests preference when reached with it off. That sentence belongs to the referrer-preference step (Step 21); both the spec and the plan say whichever of the two lands second carries it into place. This one lands first.
  • Worth a manual look: the copy. Four new strings, drafted to mirror the merged sibling's conventions (There are no packages in this repository yet / Publish your first package to get started.). I chose package and image over artifact in the headings because the page heading directly above already names the artifact.
  • Heads-up for whoever rebases next. versions_section.vue's props block auto-merges wrongly between !250140 and !250529: both add a format prop at different offsets, so git keeps both copies with no conflict marker. ESLint no-dupe-keys catches it, but it is a silent bad merge rather than a flagged one.

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.


This MR was authored with the assistance of an AI coding agent and reviewed by @zcuddy before submission.

Edited by Zack Cuddy

Merge request reports

Loading
Loading