Artifact Registry: Extract a shared repository write form
What does this MR do and why?
This change is behind the feature flag :artifact_registry_ui
Part 1 of 3, splitting !248123 (closed) into reviewable pieces. Delivers the shared form that monolith/S07 Step 7 needs, ahead of the edit flow that consumes it.
| MR | Targets | |
|---|---|---|
| 1 | Shared form extraction — this MR | 602638-repositories-list-step-4 |
| 2 | Create form followups | this MR |
| 3 | The edit flow | MR 2 |
Targets 602638-repositories-list-step-4 (!248084 (merged)). Retarget to master once that merges.
Changes
repositories_create_form.vue was simultaneously the route view, the form, and the owner of the mutation. The S07 spec calls for "one write form … parameterized by mode", so the form comes out into repositories/components/repository_form.vue and the create view becomes a thin wrapper around it.
No behaviour changes. Nothing renders differently, no string changes, and locale/gitlab.pot is untouched.
The tests move with the code they cover: the field-level assertions (format options, name validation, description limit, visibility) go to the form's own spec, and repositories_create_form_spec.js keeps what is genuinely the wrapper's — the heading, the mutation input, the cache eviction, the toast, the routing, and the error handling. Both files hold the same assertions they did, against the component that now owns each.
The extracted form is deliberately action agnostic: it owns the fields, their validators, the layout, and the submit/cancel row, and it owns no Apollo, no toast, no cache update, and no routing. It takes the values it opens with plus the verb for its submit button, and emits what the user typed. What that submit does stays with the route view — which is what keeps the create and edit experiences identical by construction rather than by convention.
Note on locale/gitlab.pot
This MR changes no strings, but the diff removes two blank lines from the pot. They are not ours: 4a86c7c6 hand-edited locale/gitlab.pot rather than regenerating it, leaving a double blank line between two ContinuousDeployment entries that the extractor does not emit. Regenerating normalises it away, and the pre-push hook (lefthook.yml, which diffs the whole file) will not let the branch push otherwise. CI's own gettext:updated_check only greps msgid lines, so it was indifferent either way.
Screenshots or screen recordings
No UI changes. This is a refactor; the create page renders exactly as it does on the target branch.
How to set up and validate locally
Read the two spec files side by side — the moved describe blocks are unchanged apart from asserting against the emitted payload instead of the mutation call. Nothing in the suite was rewritten to accommodate the refactor.
yarn jest ee/spec/frontend/packages_and_registries/artifact_registry— 128/128.VUE_VERSION=3 yarn jest ee/spec/frontend/packages_and_registries/artifact_registry— 128/128.- Optionally, with
artifact_registry_uienabled, visit/o/<your-org>/-/artifact_registry/acme/repositories/new/hostedand confirm the form looks and behaves as before.
Agent Notes
Implemented by an AI coding agent, reviewed by @zcuddy before submission.
- The
nameDisabled/showFormatcapability props the edit flow needs are not here — they arrive in MR 3 with the caller that uses them, rather than sitting unused. - The one addition to an otherwise verbatim move is
data-testid="cancel-repository", so the form's contract can be asserted without reaching through the wrapper. A testid is not behaviour. FORM_IDstays a module constant. That is safe while one route view renders at a time; if two forms ever coexist,GlFormFieldsfinds its form by id and they would collide. Noted in a comment rather than pre-solved.
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.