feat(consumers): migrate consumer groups to UI Registry#2545
Conversation
Migrate the consumer groups list, detail page, and the edit/delete offset modals from legacy @redpanda-data/ui to the Registry components. List (group-list.tsx): - TanStack useReactTable + Registry Table inside ListLayout - URL-persisted page/pageSize/sort/search (nuqs), sortable columns, pagination, and a State faceted filter (all states always available) - New useLegacyListConsumerGroupsFullQuery hook (Connect/REST) returning enriched GroupDescription (lagSum/isInUse/perms) Detail (group-details.tsx): - Registry Tabs (Topics/ACL, tab persisted in URL), Card stats bar, Accordion per topic, and a sortable+paginated PartitionTable - Disabled Edit/Delete buttons now show an explanatory tooltip - Shared ConsumerGroupStateCell (icon + state) reused by list and detail Modals (modals.tsx): - DeleteOffsetsModal -> Registry AlertDialog - EditOffsetsModal -> Registry Dialog/Select/RadioGroup/Input/Accordion + useReactTable preview tables; toasts moved to sonner - KowlTimePicker kept (no Registry datetime picker yet) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
✅ Clean — no registry drift, off-token colours, or ad-hoc classesApp:
Generated by lookout audit-changes. |
base-ui SelectValue renders the raw selected value, so the "All
Topics/Partitions" sentinel ('__all__') and the strategy keys
(endOffset, ...) leaked into the trigger. Map value -> label via a
SelectValue render function, matching the add-acl-dialog pattern.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Empty groups have no protocol/protocolType, which rendered blank stat values, and the legacy ProtocolType helper duplicated protocolType under a "Protocol" label. Show the actual group.protocol field (matching the list column) and group.protocolType with an em-dash fallback, and drop the redundant ProtocolType component. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Coordinator ID copy button used size="icon" (size-9, 36px), which was much taller than the stat label text; the flex row stretched every stat to that height, inflating the card and leaving gaps under the other labels. Shrink the copy button to size-5 and add items-start so the row hugs its natural content height. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The migrated partition action buttons use the registry (base-ui) tooltip,
which renders a `[data-slot="tooltip-content"]` popup without
role="tooltip" (the old Chakra tooltip had it). Match on the slot + text
instead of getByRole('tooltip'). No app code changed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Local e2e runs remap every host port via E2E_PORTS_OVERRIDE, but the enterprise config hardcoded shadowBackendURL to http://localhost:3101, so the shadowlink tests hit ERR_CONNECTION_REFUSED (the dest backend was on a random port). Resolve the shadow backend port from the override (falling back to 3101 for CI/static-port runs). No app code changed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move DisabledReasonButton out of group-details.tsx into src/components/ui/ so it can be reused outside consumer group details. Behavior unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two layout fixes surfaced by the group list page: - group-list rendered its table inside ListLayoutContent (flex-1), which grew to fill the min-h-screen layout and pushed the pagination bar to the bottom of the viewport. Render <Table> directly like the other list pages so pagination sits under the last row. - ListLayoutPagination did not stretch its child, so DataTablePagination collapsed to content width and its internal justify-between clustered the controls on the left. Add [&>*]:w-full so the controls span the row (also fixes topics/quotas/users/roles list pages). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…y drift The pagination full-width fix edited the vendored list-layout registry component in-place, which the UI audit flags as locally-modified drift. Revert list-layout to its released bytes and apply [&>*]:w-full via className at the ListLayoutPagination call site instead — same render, no registry drift. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Console's dialog and tabs were pinned to registry 2.3.0's predecessor
(2.2.0), which the frontend UI audit flags as outdated once the consumer
pages use them. Sync both to the 2.3.0 release:
- dialog: scroll-shadow refactor — useScrollShadow now takes the container
ref and returns axis-relative { start, end } edges (was sentinel refs +
{ top, bottom }).
- use-scroll-shadow: rewritten to the 2.3.0 geometry-based API (scroll +
ResizeObserver/MutationObserver, horizontal orientation support). Only
caller in console is DialogBody; rp-connect only mentions it in a comment.
- tabs: add ScrollableTabsList, pulling in the new drag-scroll-area dep.
- drag-scroll-area: new component from 2.3.0.
Audit now reports dialog + tabs up-to-date at 2.3.0; 0 drift.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| // Registry (base-ui) tooltip renders a `[data-slot="tooltip-content"]` popup | ||
| // without role="tooltip", so match on the slot + text instead of the role. |
There was a problem hiding this comment.
sounds like we should fix this so we can have simpler test assertions to write
| // without role="tooltip", so match on the slot + text instead of the role. | ||
| await expect( | ||
| page.locator('[data-slot="tooltip-content"]').filter({ hasText: 'No committed offset' }).first() | ||
| ).toBeVisible({ timeout: 5000 }); |
There was a problem hiding this comment.
I would refrain from using timeouts if possible
| * | ||
| * Uses the legacy REST API (same reason as {@link useLegacyListConsumerGroupsQuery}): | ||
| * authorization is only possible with Console v3 and above. | ||
| * TODO: Remove once Console v3 is released. |
There was a problem hiding this comment.
it looks like we are still using this despite console v3 being released a long time ago, should we clean it up?
There was a problem hiding this comment.
There is a separate ticket for this.
| variant?: 'ghost' | 'outline' | 'link'; | ||
| size?: 'icon-sm' | 'sm' | 'md'; |
There was a problem hiding this comment.
I would just map it from registry so it never gets out of sync, using proper types
| }, | ||
| }); | ||
|
|
||
| const dialogScrollShadow = 'pointer-events-none sticky z-10 h-0 transition-opacity duration-150'; |
There was a problem hiding this comment.
are all of these properly upstreamed?
There was a problem hiding this comment.
It's update from the UI registry (see commits)
Base UI's tooltip popup sets no ARIA role, so the disabled-action tooltip was only reachable via a [data-slot] selector. Set role="tooltip" at the call site (keeping the registry component free of drift) so it is exposed as a tooltip to assistive tech and to getByRole in tests. Derive the button variant/size props from the registry ButtonProps so they cannot drift from the Button they are forwarded to. Drop the per-assertion timeouts in the e2e spec: the Playwright config already sets a 60s expect timeout, so they were only shortening the default. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The tooltip reads "No committed offsets" (plural). Switching the assertion from a substring filter to toHaveText made the exact text matter, so the singular string no longer matched and the test timed out. Pull the string into a constant so it stays tied to group-details.tsx. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Migrates the consumer groups feature (list, detail, and the edit/delete offset modals) from the legacy
@redpanda-data/uicomponents to the Registry components — matching the already-migrated Topics/Security pages.List (
group-list.tsx)useReactTable+ RegistryTableinsideListLayoutnuqs), sortable columns, paginationuseLegacyListConsumerGroupsFullQueryhook returning enrichedGroupDescription(lagSum/isInUse/perms)Detail (
group-details.tsx)Tabs(Topics / ACL, active tab persisted in the URL),Cardstats bar,Accordionper topic, sortable + paginatedPartitionTableConsumerGroupStateCell(icon + state) reused by both list and detailModals (
modals.tsx)DeleteOffsetsModal→ RegistryAlertDialogEditOffsetsModal→ RegistryDialog/Select/RadioGroup/Input/Accordion+useReactTablepreview tables; toasts moved tosonner.KowlTimePickerkept (no Registry datetime picker yet).modals.tsxno longer imports@redpanda-data/uiat all.Test plan
bun run type:check— passbun run lint— passbun run test:integration— all consumer-group tests pass (group-details2/2); full suite green apart from one unrelated flakyobservability-pagetest that passes in isolation🤖 Generated with Claude Code