docs/superpowers/plans/2026-04-03-sa-wi-react-migration.md
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Migrate ServiceAccountPanel and WorkloadIdentityPanel from Vue to React, following the same patterns used in the UsersPage/MembersPage/GroupsPage migration.
Architecture: Create two new React pages (ServiceAccountsPage.tsx, WorkloadIdentitiesPage.tsx) that reuse the existing shared/usePagedData, shared/UserAvatar, and shared/RoleMultiSelect. Each page contains its own table and drawer components inline. Update routes to point to React pages. Delete old Vue components.
Tech Stack: React, TypeScript, Vue Router, Pinia stores via useVueState
Files:
Create: frontend/src/react/pages/settings/ServiceAccountsPage.tsx
Step 1: Create the page
Port ServiceAccountPanel.vue (231 lines) and CreateServiceAccountDrawer.vue (317 lines) into a single React page file. Follow the exact same pattern as UsersPage.tsx:
usePagedData, PagedTableFooter, UserAvatar, RoleMultiSelect from shared/ServiceAccountTable — renders active service accounts with avatar, title, email, operations (view/deactivate/restore)CreateServiceAccountDrawer — form with title, email (with domain suffix), roles (create mode only)ServiceAccountsPage function — action bar with "Add Service Account" button, active table, inactive toggle, inactive table, drawerKey stores:
useServiceAccountStore() — listServiceAccounts, createServiceAccount, updateServiceAccount, deleteServiceAccount, undeleteServiceAccount, getServiceAccountuseWorkspaceV1Store() — patchIamPolicy for role assignmentuseActuatorV1Store() — workspaceResourceNamePermissions:
bb.serviceAccounts.create — Add buttonbb.serviceAccounts.update / bb.serviceAccounts.delete / bb.serviceAccounts.undelete — row operationsbb.serviceAccounts.listEmail suffix: getServiceAccountSuffix() from @/types (returns service.bytebase.com or project-specific)
The panel currently receives a project prop but in the workspace settings context it's always undefined (workspace-level). Only handle workspace-level for this migration.
Run: pnpm --dir frontend type-check
git add frontend/src/react/pages/settings/ServiceAccountsPage.tsx
git commit -m "feat(frontend): migrate ServiceAccountPanel to React"
Files:
Create: frontend/src/react/pages/settings/WorkloadIdentitiesPage.tsx
Step 1: Create the page
Port WorkloadIdentityPanel.vue (233 lines) and CreateWorkloadIdentityDrawer.vue (743 lines) into a single React page file. Same pattern as Task 1 but with a much more complex drawer.
WorkloadIdentityTable — same pattern as ServiceAccountTable.
CreateWorkloadIdentityDrawer — complex form with:
WorkloadIdentityConfig_ProviderTypeCritical: Bidirectional subject pattern binding:
subjectPattern via computedSubjectPatternsubjectPattern changes → reverse-parse into owner/repo/branch via parseWorkloadIdentitySubjectPattern from @/utilsisUpdatingFromPattern/isUpdatingFromFields)GitHub pattern: repo:owner/repo:ref:refs/heads/branch
GitLab pattern: project_path:owner/project:ref_type:branch:ref:name
Platform change resets issuerUrl to preset, clears branch, resets refType to "all".
Key stores:
useWorkloadIdentityStore() — listWorkloadIdentities, createWorkloadIdentity, updateWorkloadIdentity, deleteWorkloadIdentity, undeleteWorkloadIdentity, getWorkloadIdentityuseWorkspaceV1Store() — patchIamPolicyuseActuatorV1Store() — workspaceResourceNameImport parseWorkloadIdentitySubjectPattern, getWorkloadIdentityProviderText from @/utils.
Import WorkloadIdentityConfig_ProviderType, WorkloadIdentityConfigSchema, WorkloadIdentitySchema from proto types.
Permissions: same pattern as ServiceAccounts but with bb.workloadIdentities.*
Run: pnpm --dir frontend type-check
git add frontend/src/react/pages/settings/WorkloadIdentitiesPage.tsx
git commit -m "feat(frontend): migrate WorkloadIdentityPanel to React"
Files:
Modify: frontend/src/router/dashboard/workspace.ts:320-340
Step 1: Update Service Accounts route
Change component from Vue ServiceAccountPanel.vue to React ReactPageMount.vue with page: "ServiceAccountsPage":
{
path: "service-accounts",
name: WORKSPACE_ROUTE_SERVICE_ACCOUNTS,
meta: {
title: () => t("settings.members.service-accounts"),
requiredPermissionList: () => ["bb.serviceAccounts.list"],
},
component: () => import("@/react/ReactPageMount.vue"),
props: () => ({ page: "ServiceAccountsPage" }),
},
Same pattern:
{
path: "workload-identities",
name: WORKSPACE_ROUTE_WORKLOAD_IDENTITIES,
meta: {
title: () => t("settings.members.workload-identities"),
requiredPermissionList: () => ["bb.workloadIdentities.list"],
},
component: () => import("@/react/ReactPageMount.vue"),
props: () => ({ page: "WorkloadIdentitiesPage" }),
},
pnpm --dir frontend type-check
git add frontend/src/router/dashboard/workspace.ts
git commit -m "feat(frontend): update routes for React SA and WI pages"
pnpm --dir frontend fix
pnpm --dir frontend check
pnpm --dir frontend type-check
git add -u
git commit -m "fix(frontend): lint and i18n fixes for SA/WI migration"