Listings Feature Matrix¶
This page audits the main UI listing surfaces in the repository and records which capabilities are enabled on each one.
Legend & Methodology¶
- Audit basis: repository state reviewed on March 21, 2026.
- Scope: visible collection surfaces backed by frontend
list*,search*, orstream*APIs. This includes routed pages and secondary list panels inside modals or assistants when they expose a real repeated-item workflow. - Included UI shapes: tables, card lists, checkbox selection panels, and reusable modal pickers.
- Excluded: tests, non-visible components, detail-only views, static option lists, simple one-off selectors that do not behave like a listing surface, and pages not backed by
list*,search*, orstream*APIs. - Shared surfaces are merged only when the same user-facing listing is reused across multiple routes. Browser is merged this way. Shared components with materially different data sources remain split by workspace.
- Values use
Yes,No, orPartial. Each capability explicitly states whether it is implemented inFE,BE, or both. Paginationnotes the dominant backend mode when present:Offset,Cursor, orMarker.Cachemeans user-visible frontend caching or a backend listing cache. When no dedicated cache layer was found, the value isNo.Selection Persistence (FE session)is FE-only. It isYeswhen selection survives the normal in-screen transitions of the listing,Partialwhen only some transitions preserve it or only still-visible items remain selected, andNowhen the listing normally clears selection on those transitions.Selection Persistence (Browser storage FE)is FE-only. It isYesonly when selection is serialized into browser storage such aslocalStorage,sessionStorage, or URL state and restored on reload or revisit.useStatealone does not count.Multi-select BEfollows a strict rule:Yesonly when one backend request accepts multiple selected items at once. FE fan-out over many single-item requests isNo. Mixed cases are markedPartial.- Out of scope under this method:
/admin/billing,/admin/endpoint-status, and metrics pages because they are not backed bylist*,search*, orstream*FE APIs.frontend/src/features/admin/ApiTokensPage.tsxbecause the page is not routed.
Admin¶
| Workspace / Route(s) | Listing Surface | Entity | Data Source (FE API + BE endpoint/service) | Search (FE/BE) | Filter (FE/BE) | Sort (FE/BE) | Pagination (FE/BE + mode) | Cache (FE/BE) | Multi-select FE | Selection Persistence (FE session) | Selection Persistence (Browser storage FE) | Multi-select BE (strict batch API) | Bulk Actions | Streaming / Live refresh | Notes / Limitations |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Admin /admin/s3-accounts |
RGW accounts table | RGW accounts | listS3Accounts -> GET /admin/accounts |
Yes (FE+BE) |
No |
Yes (BE) |
Yes (BE Offset) |
No |
No |
No |
No |
No |
No |
No |
Exact mode is FE refinement on top of BE search and may scan multiple pages before slicing the visible page. |
Admin /admin/s3-accounts |
Account edit modal linked users panel | UI users linked to one RGW account | listMinimalUsers -> GET /admin/users/minimal |
Yes (FE) |
No |
No |
No |
No |
Yes |
Yes (FE) |
No |
Yes (BE) |
Yes (FE selection, BE single save) |
No |
Selection stays in modal state while searching and editing, but it is not serialized in browser storage. |
Admin /admin/s3-users |
RGW users table | RGW users | listS3Users -> GET /admin/s3-users |
Yes (FE+BE) |
No |
No |
Yes (BE Offset) |
No |
No |
No |
No |
No |
No |
No |
Exact mode is FE refinement over paged BE results. |
Admin /admin/s3-users |
RGW user edit modal linked UI users panel | UI users linked to one RGW user | listMinimalUsers -> GET /admin/users/minimal |
Yes (FE) |
No |
No |
No |
No |
Yes |
Yes (FE) |
No |
Yes (BE) |
Yes (FE selection, BE single save) |
No |
Selection stays in modal state while searching and editing, but it is not serialized in browser storage. |
Admin /admin/s3-users/:userId/keys |
RGW user keys table | RGW user access keys | listS3UserKeys -> GET /admin/s3-users/{user_id}/keys |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
Row actions exist, but there is no multi-row selection or batch endpoint. |
Admin /admin/s3-connections |
Shared S3 connections table | Shared S3 connections | listAdminS3Connections -> GET /admin/s3-connections |
Yes (FE input, BE search) |
No |
No |
Yes (BE Offset) |
No |
Yes |
No |
No |
No |
Yes (FE fan-out) |
No |
"Select all filtered" resolves all matching ids by walking BE pages client-side. Selection is explicitly cleared on page and filter changes, so there is no in-screen persistence. |
Admin /admin/s3-connections |
Connection edit modal linked UI users panel | UI users linked to one shared connection | listS3ConnectionUsers -> GET /admin/s3-connections/{id}/userslistMinimalUsers -> GET /admin/users/minimal |
Yes (FE) |
No |
No |
No |
No |
Yes |
Yes (FE) |
No |
No |
Yes (FE fan-out) |
No |
Sync computes add/remove diffs, then executes many single-user POST and DELETE requests. Selection is kept only in modal state. |
Admin /admin/users |
UI users table | UI users | listUsers -> GET /admin/users |
Yes (BE) |
No |
Yes (BE) |
Yes (BE Offset) |
No |
No |
No |
No |
No |
No |
No |
Primary admin user inventory is fully server-driven for search, sort, and paging. |
Admin /admin/users |
UI user modal association pickers | RGW accounts, RGW users, shared S3 connections | listMinimalS3Accounts -> GET /admin/accounts/minimallistMinimalS3Users -> GET /admin/s3-users/minimallistMinimalS3Connections -> GET /admin/s3-connections/minimal |
Yes (FE) |
No |
No |
No |
No |
Yes |
Yes (FE) |
No |
Partial (BE) |
Yes (mixed) |
No |
Selection survives modal tab and query changes inside the form, but it is not restored from browser storage. |
Admin /admin/audit |
Audit trail table | Audit log entries | listAuditLogs -> GET /admin/audit/logs |
Yes (BE) |
Yes (FE+BE) |
No |
Yes (BE Cursor) |
No |
No |
No |
No |
No |
No |
No |
Role and scope filter server-side; action and status chips filter only the currently loaded window client-side. |
Admin /admin/storage-endpoints |
Storage endpoint card list | Storage endpoints | listStorageEndpoints -> GET /admin/storage-endpoints |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
Full list is fetched once and rendered as cards. No dedicated listing controls exist. |
Admin /admin/key-rotation |
Endpoint selection panel | Eligible storage endpoints | listStorageEndpoints -> GET /admin/storage-endpointsrotateS3Keys -> POST /admin/key-rotation |
No |
No |
No |
No |
No |
Yes |
Yes (FE) |
No |
Yes (BE) |
Yes (BE batch) |
No |
Selection remains in the current panel state until submission or dismissal. One request carries endpoint_ids[] and key_types[]. |
Manager¶
| Workspace / Route(s) | Listing Surface | Entity | Data Source (FE API + BE endpoint/service) | Search (FE/BE) | Filter (FE/BE) | Sort (FE/BE) | Pagination (FE/BE + mode) | Cache (FE/BE) | Multi-select FE | Selection Persistence (FE session) | Selection Persistence (Browser storage FE) | Multi-select BE (strict batch API) | Bulk Actions | Streaming / Live refresh | Notes / Limitations |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Manager /manager/buckets |
Bucket table | Buckets in selected manager context | listBuckets -> GET /manager/buckets |
No |
Yes (FE) |
Yes (FE) |
No |
Yes (BE bucket_listing_cache) |
No |
No |
No |
No |
No |
No |
Main list is unpaginated. Optional feature columns trigger a second enrichment fetch with extra include parameters. |
Manager /manager/buckets/:bucketName |
Objects tab preview list | Objects and prefixes in one bucket | listObjects -> GET /manager/buckets/{bucket_name}/objects |
No |
Partial (FE+BE) |
No |
Partial (BE Cursor) |
No |
No |
No |
No |
No |
No |
No |
Prefix navigation is BE-backed, but the UI exposes only the first page and does not surface continuation tokens. |
Manager /manager/users |
IAM users table | IAM users | listIamUsers -> GET /manager/iam/users |
Yes (FE) |
No |
Yes (FE) |
No |
No |
No |
No |
No |
No |
No |
No |
Entire IAM user list is fetched at once, then filtered and sorted client-side. |
Manager /manager/users |
Create user modal group and policy pickers | IAM groups and IAM policies | listIamGroups -> GET /manager/iam/groupslistIamPolicies -> GET /manager/iam/policies |
Partial (FE) |
No |
No |
No |
No |
Yes |
Yes (FE) |
No |
Yes (BE) |
Yes (BE single create) |
No |
Policy and group selections are retained in modal state while the create flow stays open, but there is no durable browser persistence. |
Manager /manager/users/:userName/keys |
IAM user keys table | IAM access keys | listIamAccessKeys -> GET /manager/iam/users/{user_name}/keys |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
Row actions exist, but there is no multi-row selection or batch endpoint. |
Manager /manager/groups |
IAM groups table | IAM groups | listIamGroups -> GET /manager/iam/groups |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
Entire list is loaded once; no server-side listing controls are exposed in the UI. |
Manager /manager/groups |
Create group modal policy picker | IAM policies attachable at creation time | listIamPolicies -> GET /manager/iam/policies |
Yes (FE) |
No |
No |
No |
No |
Yes |
Yes (FE) |
No |
No |
Yes (FE fan-out) |
No |
Policy selection is preserved while the create flow stays open, but it is not restored from storage. |
Manager /manager/groups/:groupName/users |
Group members table | IAM users attached to one group | listIamGroupUsers -> GET /manager/iam/groups/{group_name}/userslistIamUsers -> GET /manager/iam/users |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
Member addition uses a simple picker over the full IAM user list; there is no dedicated search or paging. |
Manager /manager/roles |
IAM roles table | IAM roles | listIamRoles -> GET /manager/iam/roles |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
Entire role list is loaded once. |
Manager /manager/roles |
Create role modal policy picker | IAM policies attachable at creation time | listIamPolicies -> GET /manager/iam/policies |
Yes (FE) |
No |
No |
No |
No |
Yes |
Yes (FE) |
No |
No |
Yes (FE fan-out) |
No |
Policy selection is preserved while the create flow stays open, but it is not restored from storage. |
Manager /manager/iam/policies |
IAM policies table | IAM policies | listIamPolicies -> GET /manager/iam/policies |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
Listing is read-mostly and fully loaded at once. |
Manager /manager/users/:userName/policies/manager/groups/:groupName/policies/manager/roles/:roleName/policies |
Entity policy pages | Attached managed policies and inline policies for one IAM entity | listUserPolicies / listGroupPolicies / listRolePolicies -> GET /manager/iam/{entity}/{name}/policieslistUserInlinePolicies / listGroupInlinePolicies / listRoleInlinePolicies -> GET /manager/iam/{entity}/{name}/inline-policieslistIamPolicies -> GET /manager/iam/policies |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
Same page combines two collections, but attach, detach, save, and delete actions remain one-by-one rather than batch. |
Manager /manager/topics |
SNS topics table | SNS topics | listTopics -> GET /manager/topics |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
Full topic list is loaded once. Policy and attributes editors open per row. |
Manager /manager/ceph/keys |
Ceph access keys table | Managed Ceph access keys | listManagerCephAccessKeys -> GET /manager/ceph/keys |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
UI-managed key is protected, but operations are still row-by-row. |
Manager /manager/bucket-compare |
Source bucket selection table | Source buckets to compare | listBuckets -> GET /manager/buckets |
No |
Yes (FE) |
Yes (FE) |
No |
Yes (BE bucket_listing_cache) |
Yes |
Yes (FE) |
No |
No |
Yes (FE selection flow) |
No |
Selection survives filter changes and compare-modal opening, but it is kept only in component state and is reset when the source context changes. |
Manager /manager/migrations |
Migration runs list | Bucket migration runs | listManagerMigrations -> GET /manager/migrations |
No |
Partial (BE) |
Yes (FE) |
Partial (BE limit only) |
No |
No |
No |
No |
No |
No |
Yes (FE polling) |
The list is refreshed every 5 seconds, but the UI has no pager and requests a fixed limit=100. |
Manager /manager/migrations/new |
Migration wizard source bucket selector | Source buckets to migrate | listBuckets -> GET /manager/buckets |
No |
Yes (FE) |
Yes (FE) |
No |
Yes (BE bucket_listing_cache) |
Yes |
Yes (FE) |
No |
No |
Yes (FE select filtered) |
No |
Selection survives wizard step changes and filter changes, but it is stored only in component state. Source context changes reconcile the selection to still-existing buckets. |
Manager /manager/migrations/:migrationId |
Migration detail item list | Per-bucket migration items | streamManagerMigration -> GET /manager/migrations/{id}/streamgetManagerMigration -> GET /manager/migrations/{id} |
No |
Yes (FE) |
Yes (FE) |
No |
No |
No |
No |
No |
No |
Yes (FE list-level ops) |
Yes (BE SSE with FE polling fallback) |
Focus filters and priority sorting are FE-only. Bulk retry or rollback actions operate on status-derived subsets, not on explicit row selection. |
Browser¶
| Workspace / Route(s) | Listing Surface | Entity | Data Source (FE API + BE endpoint/service) | Search (FE/BE) | Filter (FE/BE) | Sort (FE/BE) | Pagination (FE/BE + mode) | Cache (FE/BE) | Multi-select FE | Selection Persistence (FE session) | Selection Persistence (Browser storage FE) | Multi-select BE (strict batch API) | Bulk Actions | Streaming / Live refresh | Notes / Limitations |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Browser /browser/manager/browser/ceph-admin/browser |
Bucket menu and bucket search list | Buckets visible in browser context | searchBrowserBuckets -> GET /browser/buckets/search |
Yes (BE) |
No |
No |
Yes (BE Offset) |
Yes (BE cache) |
No |
No |
No |
No |
No |
No |
Same surface is embedded in root browser, manager browser, and ceph-admin browser. On /browser, the same listing also feeds the pinned left bucket panel. Exact bucket checks reuse the same endpoint with exact=true. |
Browser /browser/manager/browser/ceph-admin/browser |
Object explorer list | Objects and prefixes in the current bucket | listBrowserObjects -> GET /browser/buckets/{bucket_name}/objects |
Yes (FE+BE) |
Yes (FE+BE) |
Yes (FE) |
Yes (BE Cursor) |
Yes (BE cache) |
Yes |
Partial (FE) |
No |
Partial (BE) |
Yes (mixed) |
No |
Selection exists in FE state, but it is pruned to still-visible items when the visible list changes and is cleared on context switches. It is not serialized in browser storage. |
Browser /browser/manager/browser/ceph-admin/browser |
Versions and deleted objects lists | Object versions and delete markers | listObjectVersions -> GET /browser/buckets/{bucket_name}/versions |
Partial (BE key/prefix scoping only) |
Partial (FE+BE) |
Partial (FE) |
Yes (BE Marker) |
No |
No |
No |
No |
No |
No |
No |
Modal and side-panel variants reuse the same BE listing. Ordering is rendered client-side from returned version timestamps. |
Browser /browser/manager/browser/ceph-admin/browser |
Multipart uploads modal list | In-progress multipart uploads | listMultipartUploads -> GET /browser/buckets/{bucket_name}/multipart |
No |
No |
No |
Yes (BE Marker) |
No |
No |
No |
No |
No |
No |
No |
Abort is row-by-row only. UI enforces a hard limit and asks the user to narrow scope when exceeded. |
Ceph Admin¶
| Workspace / Route(s) | Listing Surface | Entity | Data Source (FE API + BE endpoint/service) | Search (FE/BE) | Filter (FE/BE) | Sort (FE/BE) | Pagination (FE/BE + mode) | Cache (FE/BE) | Multi-select FE | Selection Persistence (FE session) | Selection Persistence (Browser storage FE) | Multi-select BE (strict batch API) | Bulk Actions | Streaming / Live refresh | Notes / Limitations |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Ceph Admin all routes |
Topbar endpoint selector | Ceph-compatible storage endpoints | listCephAdminEndpoints -> GET /ceph-admin/endpoints |
No |
No |
Yes (BE) |
No |
No |
No |
Yes (FE) |
Yes (FE localStorage) |
No |
No |
No |
Endpoint order is server-side by name. The selected endpoint is kept in URL state and localStorage. Optional compact color-coded endpoint tags are rendered only when the user enables the local selector-tags preference from /profile, and only tags with scope = standard are exposed there. |
Ceph Admin /ceph-admin/accounts |
RGW accounts table | Endpoint-scoped RGW accounts | listCephAdminAccounts -> GET /ceph-admin/endpoints/{endpoint_id}/accounts |
Yes (FE+BE) |
Yes (FE+BE) |
Yes (BE) |
Yes (BE Offset) |
No |
No |
No |
No |
No |
No |
No |
Debounced quick search plus JSON advanced filter. Extra stats columns trigger a second detail fetch with include=stats. |
Ceph Admin /ceph-admin/users |
RGW users table | Endpoint-scoped RGW users | listCephAdminUsers -> GET /ceph-admin/endpoints/{endpoint_id}/users |
Yes (FE+BE) |
Yes (FE+BE) |
Yes (BE) |
Yes (BE Offset) |
No |
No |
No |
No |
No |
No |
No |
Detail columns are progressively enriched through a second request with include parameters. |
Ceph Admin /ceph-admin/users |
User edit modal key table | Ceph RGW access keys for one user | listCephAdminUserKeys -> GET /ceph-admin/endpoints/{endpoint_id}/users/{user_id}/keys |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
Key lifecycle remains row-by-row even though the modal also exposes create and generated-secret flows. |
Ceph Admin /ceph-admin/buckets |
Bucket operations workbench | Endpoint-scoped buckets | listCephAdminBuckets -> GET /ceph-admin/endpoints/{endpoint_id}/bucketsstreamCephAdminBuckets -> GET /ceph-admin/endpoints/{endpoint_id}/buckets/stream |
Yes (FE+BE) |
Yes (FE+BE) |
Yes (BE) |
Yes (BE Offset) |
Yes (BE cache) |
Yes |
Yes (FE) |
Yes (FE localStorage) |
No |
Yes (FE fan-out) |
Partial (BE SSE) |
Shared workbench with deep bulk config flows. Selection, filters, paging, and sorting are restored from localStorage, keyed by endpoint. SSE is used for advanced search progress, not for continuous live updates of the whole page. |
Storage Ops¶
| Workspace / Route(s) | Listing Surface | Entity | Data Source (FE API + BE endpoint/service) | Search (FE/BE) | Filter (FE/BE) | Sort (FE/BE) | Pagination (FE/BE + mode) | Cache (FE/BE) | Multi-select FE | Selection Persistence (FE session) | Selection Persistence (Browser storage FE) | Multi-select BE (strict batch API) | Bulk Actions | Streaming / Live refresh | Notes / Limitations |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Storage Ops /storage-ops/buckets |
Bucket operations workbench | Cross-context buckets | listStorageOpsBuckets -> GET /storage-ops/bucketsstreamStorageOpsBuckets -> GET /storage-ops/buckets/stream |
Yes (FE+BE) |
Yes (FE+BE) |
Yes (BE) |
Yes (BE Offset) |
Yes (BE cache) |
Yes |
Yes (FE) |
Yes (FE localStorage) |
No |
Yes (FE fan-out) |
Partial (BE SSE) |
Same shared workbench family as Ceph Admin, but with extra context and endpoint filters and a storage-ops-specific backend route. Selection, filters, paging, and sorting are restored from localStorage, keyed by endpoint. |
Shared / Cross-workspace¶
| Workspace / Route(s) | Listing Surface | Entity | Data Source (FE API + BE endpoint/service) | Search (FE/BE) | Filter (FE/BE) | Sort (FE/BE) | Pagination (FE/BE + mode) | Cache (FE/BE) | Multi-select FE | Selection Persistence (FE session) | Selection Persistence (Browser storage FE) | Multi-select BE (strict batch API) | Bulk Actions | Streaming / Live refresh | Notes / Limitations |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Shared /profile |
Private S3 connections table | User-owned private S3 connections | listConnections -> GET /connections |
Yes (FE) |
Yes (FE) |
Yes (FE) |
Yes (FE Offset) |
No |
Yes |
Partial (FE) |
No |
No |
Yes (FE fan-out) |
No |
The full list is loaded once, then filtered, sorted, paged, and bulk-operated entirely in the frontend. Connection tags are displayed inline with shared per-owner colors, edited from the main modal form through an inline tag row plus per-tag popover, included in the FE filter haystack, and remain owner-editable only. Tags can be marked administrative to stay in management surfaces only; selector APIs expose only standard tags. Selection is reconciled with the active filter and cleared on page or page-size changes. |
Shared reusable modal in manager and ceph-admin key flows |
Add S3 Connection from key modal endpoint preset list | Configured storage endpoints reusable as connection presets | listStorageEndpoints -> GET /admin/storage-endpoints |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
No |
Reused after key generation flows. This is a lightweight picker rather than a full management table, but it is still a visible API-backed listing surface in a cross-workspace workflow. |
Coverage Notes¶
- Browser was intentionally merged across
/browser,/manager/browser, and/ceph-admin/browserbecause the same listing surface is embedded under three routes. - Ceph Admin and Storage Ops bucket workbenches stay split because the UI family is shared, but the routes, backend endpoints, scope model, and filter dimensions differ.
- The two selection-persistence columns are intentionally narrower than
Multi-select FE: Selection Persistence (FE session)captures in-screen retention only.Selection Persistence (Browser storage FE)requires explicit browser-backed restoration.- The main
Partialcases are: - Browser object explorer, where selection is retained only for still-visible items and is cleared on context switches.
- Profile private connections, where filtering keeps only still-matching selections but pagination clears them.
- The strict backend batch rule still changes several outcomes:
Yes: admin key rotation, admin account linked-users save, admin RGW user linked-users save, and the S3 user/connection parts of admin UI-user association saves.Partial: browser object explorer, because only delete uses a strict batch request.No: shared S3 connections bulk actions, profile private connection bulk actions, manager bucket workbench bulk actions, and most IAM attach/detach flows, because they are FE orchestration over many single-item requests.