feat(consumers): migrate consumer groups to UI Registry - #2545
Open
jvorcak wants to merge 21 commits into
Open
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>
Contributor
🚨 Registry drift detectedApp:
Components needing attention
Refresh command: bunx shadcn@latest add @redpanda/stat --overwriteGenerated 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>
Comment on lines
+137
to
+138
| // Registry (base-ui) tooltip renders a `[data-slot="tooltip-content"]` popup | ||
| // without role="tooltip", so match on the slot + text instead of the role. |
Contributor
There was a problem hiding this comment.
sounds like we should fix this so we can have simpler test assertions to write
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>
eblairmckee
reviewed
Jul 14, 2026
eblairmckee
reviewed
Jul 14, 2026
eblairmckee
reviewed
Jul 14, 2026
eblairmckee
reviewed
Jul 14, 2026
eblairmckee
reviewed
Jul 14, 2026
eblairmckee
reviewed
Jul 14, 2026
eblairmckee
reviewed
Jul 14, 2026
eblairmckee
reviewed
Jul 14, 2026
eblairmckee
reviewed
Jul 14, 2026
eblairmckee
reviewed
Jul 14, 2026
eblairmckee
reviewed
Jul 14, 2026
Adopt the registry Stat component for the group list and detail stats bars, replacing the hand-rolled label/value stacks. Swap both search fields to registry Input + InputStart/InputEnd so the padding and icon positioning come from the component instead of ad-hoc absolute positioning, and associate the "topics with lag" checkbox with a registry Label via htmlFor. Drop the activeClassName="after:bg-foreground" override on the tabs so the underline uses the registry's intended after:bg-selected, and remove the hover:bg-transparent override on the empty-state row: TableRow has no hover background, only data-[state=selected], which this row never gets. Hoist the column meta type out of render into a shared module, derived from the registry's tableHeadVariants so it cannot drift, and compose the disabled trigger in DisabledReasonButton from buttonVariants rather than hardcoding h-8 w-8. stat.tsx is vendored from ui-registry v2.3.0 to match the tagged release the audit classifies against. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…er-groups-to-ui-registry # Conflicts: # frontend/src/routes/groups/$groupId.tsx
SpicyPete
reviewed
Jul 20, 2026
| @@ -0,0 +1,171 @@ | |||
| import { cva, type VariantProps } from 'class-variance-authority'; | |||
Contributor
There was a problem hiding this comment.
Minor: Registry has a newer version of stat, lets re-pull this in
SpicyPete
reviewed
Jul 20, 2026
Contributor
|
This PR is becoming a bit stale, can it be rebased + fix the lint errors and I'll take another look at it |
The merge from master clobbered GroupList's return JSX with a leftover fragment from master's old GroupId helper (undefined protocol/groupIdEl refs), and an earlier "remove console ai features" cleanup deleted the whole react-query/api/consumer-group.tsx file instead of just the AI-only export, taking useLegacyListConsumerGroupsFullQuery with it. Restore the pre-merge return statement (ListLayout/Stat/filters/table/ pagination) and re-add useLegacyListConsumerGroupsFullQuery.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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