Skip to content

fix(api-manager): accessible loading status on the skeleton gate - #12541

Open
pacocartones wants to merge 2 commits into
diegosouzapw:release/v3.8.51from
pacocartones:fix/api-manager-skeleton-a11y-status
Open

fix(api-manager): accessible loading status on the skeleton gate#12541
pacocartones wants to merge 2 commits into
diegosouzapw:release/v3.8.51from
pacocartones:fix/api-manager-skeleton-a11y-status

Conversation

@pacocartones

Copy link
Copy Markdown
Contributor

Summary

  • ApiManagerPageClient.tsx:950-956 returns nothing but two <CardSkeleton /> while the initial /api/keys fetch is pending, and CardSkeleton (src/shared/components/Loading.tsx:96-105) is aria-hidden="true" with no role="status" alongside it. For the whole loading window the API Keys page has no accessible content at all: a screen reader or any tool inspecting the accessibility tree sees only the sidebar, which is the "page is empty" / "API Keys link does nothing" reading in fix: /dashboard/api-manager renders blank (only sidebar visible) #12066 and its duplicate [BUG] Home Quick Start 'API Keys' link does not navigate #12065.
  • The two skeletons are now wrapped in the same role="status" aria-live="polite" aria-busy="true" container the other dashboard loading states already use (providers/loading.tsx:7, analytics/loading.tsx:7, settings/loading.tsx:7; same pattern as PageLoading in Loading.tsx:69-77 and the Profile gate from fix(profile): expose accessible status and progress #11838), with a visually hidden common.loading label. common.loading already exists in every locale, so no message file changes.
  • Loading.tsx is deliberately untouched: CardSkeleton has 30 usages across 18 files and three route-level loading.tsx files already wrap it in a status container, so giving the skeleton itself a role would nest live regions. The fix is local to the one gate that had none. No layout change: the wrapper keeps flex flex-col gap-8, the label is sr-only, and the status disappears with the gate once loading clears (the finally in fetchData, so it clears on both success and failure).

Related Issues

Validation

  • Change type: UI
  • Focused tests and category gates from the golden path: vitest run --config vitest.config.ts tests/unit/ui/api-manager-loading-status-12066.test.tsx 2/2, node scripts/check/check-complexity-ratchets.mjs --base-ref origin/release/v3.8.51 OK, npm run check:changelog-integrity OK, eslint exit 0 and prettier --check clean on the touched files
  • npm run lint
  • Reconciled with the current active release base release/v3.8.51; focused checks rerun afterward
  • Production-code changes include a new or updated automated test in this PR
  • SonarQube is temporarily opt-in while the private project has no quota; it is not a PR gate.

Tests Added Or Updated

  • tests/unit/ui/api-manager-loading-status-12066.test.tsx (new, 2 cases): mounts ApiManagerPageClient in jsdom with next-intl mocked. Case 1 keeps fetch pending forever and asserts a [role="status"] with aria-live="polite", aria-busy="true" and the loading label exists while the skeleton cards stay aria-hidden. Case 2 resolves fetch and asserts the status is gone and the page <h1> is rendered. Red on the base (expected null not to be null on the status query), green with the change.

Coverage Notes

  • src/app/(dashboard)/dashboard/api-manager/ApiManagerPageClient.tsx: the loading branch is now exercised by the new test in both states (pending and settled); the rest of the file is unchanged and keeps its existing coverage from tests/unit/api-manager-*.test.ts.
  • No touched file lost coverage.

Reviewer Notes

  • One 4-line change in the loading gate plus a test; nothing else moves. If you would rather have the status semantics on CardSkeleton itself, that is a wider change across its call sites and the three loading.tsx pages that already wrap it would end up with nested live regions, so I kept it out of this PR.
  • The changelog fragment is named PENDING-api-manager-skeleton-a11y-status.md; I will rename it to the PR number once assigned.

While the initial /api/keys fetch is pending, ApiManagerPageClient renders
only two CardSkeleton cards, and CardSkeleton is aria-hidden. For the whole
loading window the page therefore has no accessible content at all: screen
readers and automated tooling see only the sidebar, which is the "API Keys
page is empty" reading in the report.

Wrap the two skeletons in the same role="status" aria-live="polite"
aria-busy="true" container the other dashboard loading states already use,
with a visually hidden common.loading label. Loading.tsx is left untouched
so its other callers keep their current semantics.

Closes diegosouzapw#12066
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: /dashboard/api-manager renders blank (only sidebar visible)

1 participant