Add Vue 3 rollout metadata for seat management pages
What does this MR do and why?
Moves the 24 page entrypoints owned by group::seat management to Vue 3, behind our own
feature flag vue3_migrate_seat_management. The flag is off by default, so there is no
change in production until we enable it.
The repo-wide final sweep (!261154 (merged)) merged with these entrypoints excluded, so they are currently still on Vue 2. An own flag gives us a rollback lever scoped to our pages instead of one shared with every other laggard.
Each entrypoint gets a vue3_migration.yml next to its index.js. admin/users and
admin/users/edit exist in both CE and EE, so they get two identical copies, as the
loader requires. That is 26 yml files for 24 entry names, plus the flag definition.
status: rollout
feature_flag: vue3_migrate_seat_management
group: group::seat management
migration_issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/633485Ownership comes from the Vue 3 migration dashboard
(https://vue3-migration-dashboard-0afc95.gitlab.io/), which attributes an entrypoint by
its controller's feature_category. .gitlab/CODEOWNERS is not usable for this: it has
no app/assets rules for Fulfillment, so every path falls through to the frontend
maintainers catch-all.
Screenshots or screen recordings
No UI change while the flag is off.
How to set up and validate locally
- Enable the flag:
Feature.enable(:vue3_migrate_seat_management). - Restart vite, then open one of the pages below.
- Confirm the page requests
<entry>.vue3.jsand that the console logs[V] Using Vue.js 3 for <AppName>.
Verification
All 24 entrypoints were loaded in a browser with the flag on, against an Ultimate licence.
Every page served its .vue3.js entrypoint, mounted its app under @vue/compat, and
logged no console errors.
| # | Entrypoint | URL | Apps mounted under Vue 3 |
|---|---|---|---|
| 1 | pages.admin.application_settings.roles_and_permissions |
/admin/application_settings/roles_and_permissions |
RolesRoot |
| 2 | …roles_and_permissions.new |
…/roles_and_permissions/new |
CreateRoleRoot |
| 3 | …roles_and_permissions.show |
…/roles_and_permissions/:id |
RoleDetailsRoot |
| 4 | …roles_and_permissions.edit |
…/roles_and_permissions/:id/edit |
EditRoleRoot |
| 5 | pages.groups.settings.roles_and_permissions |
/groups/:g/-/settings/roles_and_permissions |
RolesRoot |
| 6 | …roles_and_permissions.new |
…/roles_and_permissions/new |
CreateRoleRoot |
| 7 | …roles_and_permissions.show |
…/roles_and_permissions/:id |
RoleDetailsRoot |
| 8 | …roles_and_permissions.edit |
…/roles_and_permissions/:id/edit |
EditRoleRoot |
| 9 | pages.admin.application_settings.service_accounts |
/admin/application_settings/service_accounts |
ServiceAccountsRoot, CustomBreadcrumbsRoot |
| 10 | pages.groups.settings.service_accounts.index |
/groups/:g/-/settings/service_accounts |
ServiceAccountsRoot, CustomBreadcrumbsRoot |
| 11 | pages.projects.settings.service_accounts.index |
/:g/:p/-/settings/service_accounts |
ServiceAccountsRoot, CustomBreadcrumbsRoot |
| 12 | pages.admin.users |
/admin/users |
AdminUsersAppRoot, AdminUsersFilterAppRoot, DeleteUserModalRoot, ConfirmModalRoot |
| 13 | pages.admin.users.edit |
/admin/users/:user/edit |
PasswordInputRoot, UserTypeSelectorRoot, ResetButtonRoot |
| 14 | pages.admin.users.new |
/admin/users/new |
UserTypeSelectorRoot |
| 15 | pages.admin.credentials |
/admin/credentials |
CredentialsFilterSortAppRoot |
| 16 | pages.admin.impersonation_tokens |
/admin/users/:user/impersonation_tokens |
AccessTokenTableRoot, ExpiresAtFieldRoot, NewAccessTokenRoot, AdminUserActionsRoot |
| 17 | pages.admin.keys |
/admin/users/:user/keys/:id |
ConfirmModalRoot |
| 18 | pages.admin.role_promotion_requests |
/admin/role_promotion_requests |
PromotionRequestsAppWrapper |
| 19 | pages.admin.gitlab_duo.seat_utilization |
/admin/gitlab_duo/seat_utilization |
CodeSuggestionsUsage |
| 20 | pages.groups.ldap_group_links |
/groups/:g/-/ldap_group_links |
GroupLinkRoleSelectorRoot, GroupSelectRoot |
| 21 | pages.groups.saml_group_links |
/groups/:g/-/saml_group_links |
GroupLinkRoleSelectorRoot |
| 22 | pages.groups.security.credentials |
/groups/:g/-/security/credentials |
CredentialsFilterSortAppRoot, ConfirmModalRoot |
| 23 | pages.groups.usage_quotas.pending_members |
/groups/:g/-/usage_quotas/pending_members |
PendingMembersAppRoot |
| 24 | pages.users.terms.index |
/-/users/terms |
TermsAppRoot |
Rows 1-4, 15, 18, 19 and 20 are self-managed only and were checked with
GITLAB_SIMULATE_SAAS=0; rows 5-8, 21, 22 and 23 need SaaS mode and were checked with
GITLAB_SIMULATE_SAAS=1.
Beyond page load, the create-role form was submitted end to end on both row 2 and row 6:
the base-role dropdown, the permission checkboxes and the submit all behaved correctly
under Vue 3, and the created role then rendered on the show and edit pages.
The one non-Vue console error seen, and why it is unrelated
On /admin/gitlab_duo/seat_utilization the page logs an Apollo error. The only failing
request is POST /-/customers_dot/proxy/graphql returning 404, so the proxy returns an
HTML error page where Apollo expects JSON. The page itself mounts CodeSuggestionsUsage
and renders.
This is not reachable locally for this page, with or without CustomersDot running:
CustomersDot::ProxyControllerrenders 404 unlessGitlab::Saas.feature_available?(:cdot_graphql_proxy), which is justGitlab::Saas.enabled?(ee/lib/gitlab/saas.rb:67), so it needs SaaS mode.Admin::GitlabDuo::SeatUtilizationControllerrenders 404 unless!gitlab_com_subscription?, so the page needs self-managed mode.
The two conditions are mutually exclusive on one instance, so the proxy can never answer
for this page locally. Starting CustomersDot on localhost:5000 does not change the
result.
It is also independent of this MR: with vue3_migrate_seat_management disabled, the same
page loads the Vue 2 bundles and produces the identical 404 and the identical Apollo
error.
Why data-gitlab-vue3-app is not the signal used here
doc/development/fe_guide/vue3_migration.md suggests checking
document.querySelectorAll('[data-gitlab-vue3-app]'). That attribute is only stamped when
an app is constructed through the compat wrapper with an el option
(app/assets/javascripts/lib/utils/vue3compat/vue.js:55 and mount_wrapper.js:44). Pages
whose apps mount another way return nothing even though they do run under Vue 3 — the
roles show page is one such case. The checks above therefore use the loaded
<entry>.vue3.js bundle plus the [V] Using Vue.js 3 for <AppName> dev notice, which hold
for every mount path.
Automated checks:
node -e 'require("./config/vue3migration/migration.js").loadVue3Migrations()'resolves all 24 entry names, with no CE/EE divergence.spec/lib/gitlab/vue3_migration_files_spec.rb— 3221 examples, 0 failures.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist.
References
- Rollout issue: #633485
- Final sweep MR that excluded these entrypoints: !261154 (merged)
- Vue 3 migration epic: &23285