Skip to content

[refactor] The table's peripheral chrome comes off antd - #5961

Open
ardaerzin wants to merge 1 commit into
obs/table-class-hooksfrom
obs/table-peripheral-chrome
Open

[refactor] The table's peripheral chrome comes off antd#5961
ardaerzin wants to merge 1 commit into
obs/table-class-hooksfrom
obs/table-peripheral-chrome

Conversation

@ardaerzin

Copy link
Copy Markdown
Contributor

Context

@agenta/ui's table package was antd well beyond the <Table> it renders. Nine files pulled in Typography, Skeleton, Tooltip, Popover, Dropdown, Checkbox and Grid.useBreakpoint, so "the table depends on antd" was much bigger than the one component that actually needs replacing.

Step 2 of docs/design/observability-packages/plan.md §8 shrinks that to the render leaf, which is what makes step 3 a single-file project.

Changes

The swaps go onto the primitives WP3 established. Two are worth calling out.

Grid.useBreakpoint()useIsNarrowScreen(). Both call sites only ever read !screens.lg, so the replacement is a small matchMedia hook on antd's own lg value (992px), living in @agenta/ui/hooks where mobile can use it too.

MenuProps["items"]TableMenuItem[]. The hooks that build menus now return a plain descriptor and one renderer turns it into dropdown-menu parts:

{key, label, icon?, disabled?, danger?, onClick?, children?} | {type: "divider"}

That also drops the antd-shaped onClick(e.domEvent) from the package's public ActionItem. No consumer used the event argument. Stopping propagation is the renderer's job now, so an item's onClick takes nothing.

A live bug goes with it. The column-visibility gear did nothing when clicked. Its trigger called preventDefault(), and a default-prevented event makes antd and Radix both skip the open handler composed onto the same element. What that handler wanted was stopPropagation(), so the header cell does not sort out from under the click. It now does only that, and the gear opens.

Tests / notes

  • OSS, EE, mobile and @agenta/ui typecheck. @agenta/ui lints clean; @agenta/entity-ui is 330 tests green.
  • Two OSS call sites were still building antd menu items for settingsDropdownMenuItems (EvalRunDetails and TestcasesTableNew); both now build TableMenuItem[].
  • Two antd components stay in the package, deliberately. Table is step 3 and the point of the sequence. Pagination has no @agenta/ui equivalent, and building one means page numbers, ellipsis and a total count, which is new UI that wants a design pass rather than an invented primitive. One page (ApplicationManagementSection) renders paginationMode="paginated".
  • Also deferred: the checkable Tree inside ColumnVisibilityPopoverContent, for the same reason — there is no checkable-tree primitive to swap onto. Its sibling ColumnVisibilityTrigger uses a recursive checkbox list and is ported here, so the pattern for a later port already exists.
  • I could not run this against a browser (no dev server was up), so the QA below matters more than usual.

What to QA

Every change is a visual swap, so the risk is a control that looks or behaves subtly differently.

  • Any table's gear icon: it opens. This is the fix, and on main the icon does nothing on several tables.
  • In that popover: checkboxes toggle, a group checkbox shows the mixed state when only some children are on, Reset and Close work.
  • A table with the settings dropdown (test cases, evaluation run details): the gear opens a menu with Column visibility, Row height, Export to CSV and Delete. Row height opens a submenu and the current size reads bold.
  • Choosing Column visibility from that menu opens the visibility popover anchored to the same gear.
  • A row's actions menu: items fire, destructive items are red, dividers sit between groups and never at an edge.
  • Narrow the window below 992px: the delete and export buttons move into the settings dropdown, and widening moves them back.
  • Table description text and the loading skeleton in a resizable header cell still look right in both themes.

Step 2 of the table port. Everything in the package except the render leaf was
still antd: Typography, Skeleton, Tooltip, Popover, Dropdown, Checkbox and
Grid.useBreakpoint across nine files.

The swaps are onto the primitives WP3 established. Grid.useBreakpoint becomes
useIsNarrowScreen, a matchMedia hook on antd's own lg breakpoint, which is all
the two call sites ever asked it for. antd's MenuProps becomes TableMenuItem, a
plain descriptor the menu-building hooks return and one renderer turns into
dropdown-menu parts. That also drops the antd-shaped onClick(e.domEvent) from
the package's public ActionItem, which no consumer was using.

This fixes a live bug on the way. The column-visibility gear did nothing when
clicked: its trigger called preventDefault, and a default-prevented event makes
both antd and Radix skip the open handler composed onto the same element.
Stopping propagation is what that handler actually wanted, so the header cell
does not sort out from under the click.

Two antd components stay, and neither is a swap that WP3 established:

- Table, which is step 3 and the whole point of the sequence.
- Pagination, which has no @agenta/ui equivalent. Building one means page
  numbers, ellipsis and a total, which is new UI and wants a design pass, not
  a 4am hand-roll. One page renders paginationMode="paginated".

Also deferred: the checkable Tree inside ColumnVisibilityPopoverContent. It
needs a checkable-tree primitive that does not exist, so the same argument
applies.
@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Blocked Blocked Aug 12, 2026 1:15am

Request Review

@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. frontend refactoring A code change that neither fixes a bug nor adds a feature labels Aug 12, 2026
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added consistent table menus with support for nested items, dividers, icons, disabled states, and destructive actions.
    • Improved column visibility and table settings controls with clearer labels and responsive behavior.
    • Added responsive detection for narrow screens and updated table tabs and controls accordingly.
  • Enhancements
    • Improved accessibility and interaction behavior for table controls, menus, and tooltips.
    • Standardized loading placeholders, descriptions, and selected row-height styling across tables.
    • Added support for configurable row height and type-chip menus using the updated table menu experience.

Walkthrough

The change adds shared table menu and media-query primitives, then migrates InfiniteVirtualTable and related OSS components from Ant Design menu, tooltip, popover, checkbox, typography, skeleton, breakpoint, and tabs APIs.

Changes

Infinite table UI migration

Layer / File(s) Summary
Shared menu and responsive primitives
web/packages/agenta-ui/src/InfiniteVirtualTable/tableMenu.tsx, web/packages/agenta-ui/src/InfiniteVirtualTable/index.ts, web/packages/agenta-ui/src/hooks/*
Adds TableMenuItem, recursive renderTableMenuItems, useMediaQuery, and useIsNarrowScreen.
Menu contracts and action flows
web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/*, web/packages/agenta-ui/src/InfiniteVirtualTable/columns/createStandardColumns.tsx, web/packages/agenta-ui/src/InfiniteVirtualTable/components/columnVisibility/TableSettingsDropdown.tsx, web/packages/agenta-ui/src/InfiniteVirtualTable/features/InfiniteVirtualTableFeatureShell.tsx, web/oss/src/components/EvalRunDetails/hooks/useRowHeightMenuItems.tsx, web/oss/src/components/TestcasesTableNew/components/TestcasesTableShell.tsx
Replaces Ant Design menu item types with TableMenuItem[] and removes menu event parameters from action callbacks.
Table control component migration
web/packages/agenta-ui/src/InfiniteVirtualTable/components/ColumnVisibilityTrigger.tsx, web/packages/agenta-ui/src/InfiniteVirtualTable/components/TableDescription.tsx, web/packages/agenta-ui/src/InfiniteVirtualTable/components/common/ResizableTitle.tsx, web/packages/agenta-ui/src/InfiniteVirtualTable/columns/createStandardColumns.tsx
Uses local checkbox, popover, tooltip, paragraph, skeleton, and styled fallback components.
Responsive tabs and table shell
web/packages/agenta-ui/src/InfiniteVirtualTable/features/InfiniteVirtualTableFeatureShell.tsx, web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useTableManager.tsx
Replaces Ant Design breakpoint, tabs, and disabled-action tooltip usage with shared hooks and components.

Estimated code review effort: 4 (Complex) | ~45 minutes

Mergeability Score: 🔵 Low · up to e3233

The refactor is broadly mergeable, but it leaves two bounded UI issues: table descriptions may have extra vertical spacing, and some composed controls may not receive refs correctly under React 18, which can affect trigger behavior or accessibility. These should have explicit owner follow-up.

Sequence Diagram(s)

sequenceDiagram
  participant TableUser
  participant InfiniteVirtualTableFeatureShell
  participant renderTableMenuItems
  participant TableAction
  TableUser->>InfiniteVirtualTableFeatureShell: open a table menu
  InfiniteVirtualTableFeatureShell->>renderTableMenuItems: pass TableMenuItem[]
  renderTableMenuItems->>TableAction: invoke the selected callback
  TableAction->>InfiniteVirtualTableFeatureShell: update action state
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 60.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main refactor: removing peripheral Ant Design dependencies from the table package.
Description check ✅ Passed The description directly explains the table refactor, API changes, bug fix, deferred work, and validation notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch obs/table-peripheral-chrome

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Preview URL https://gateway-pr-5961.up.railway.app/w
Project agenta-oss-clone-spike
Image tag pr-5961-85705f9
Status Deployed
Railway logs Open logs
Workflow logs View workflow run
Updated at 2026-08-12T01:28:21.556Z

@ardaerzin

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 544bbb51-8943-4f05-a0ba-47f4465c4faf

📥 Commits

Reviewing files that changed from the base of the PR and between 8a73bd4 and e323359.

📒 Files selected for processing (16)
  • web/oss/src/components/EvalRunDetails/hooks/useRowHeightMenuItems.tsx
  • web/oss/src/components/TestcasesTableNew/components/TestcasesTableShell.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/columns/createStandardColumns.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/components/ColumnVisibilityTrigger.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/components/TableDescription.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/components/columnVisibility/TableSettingsDropdown.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/components/common/ResizableTitle.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/features/InfiniteVirtualTableFeatureShell.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useRowHeight.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useRowHeightFeature.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useTableManager.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/hooks/useTypeChipFeature.tsx
  • web/packages/agenta-ui/src/InfiniteVirtualTable/index.ts
  • web/packages/agenta-ui/src/InfiniteVirtualTable/tableMenu.tsx
  • web/packages/agenta-ui/src/hooks/index.ts
  • web/packages/agenta-ui/src/hooks/useMediaQuery.ts

Comment on lines +116 to +120
{/* Tooltip outside, popover trigger inside: each `asChild` clones down to the same
button, so both sets of handlers compose onto it. */}
<SimpleTooltip title={variant === "icon" ? label : undefined}>
<PopoverTrigger asChild>{triggerNode}</PopoverTrigger>
</SimpleTooltip>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 4 'function (DropdownMenuTrigger|PopoverTrigger)' \
  web/packages/agenta-ui/src/components/ui/{dropdown-menu,popover}.tsx

rg -n -C 4 'SimpleTooltip|DropdownMenuTrigger asChild|PopoverTrigger asChild' \
  web/packages/agenta-ui/src/InfiniteVirtualTable/{columns/createStandardColumns.tsx,components/ColumnVisibilityTrigger.tsx,components/columnVisibility/TableSettingsDropdown.tsx}

fd -a '^package.json$' web -x rg -n '"react"\s*:' {}

Repository: Agenta-AI/agenta

Length of output: 14167


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- package/runtime declarations ---'
fd -a '^package.json$' web -x sh -c 'printf "\n%s\n" "$1"; rg -n -C 2 "\"(react|react-dom|`@radix-ui/react-`(tooltip|popover|dropdown-menu))\"" "$1"' sh {}

printf '%s\n' '--- tooltip implementation and primitive imports ---'
fd -a 'tooltip-composed.tsx|tooltip.tsx|button.tsx|popover.tsx|dropdown-menu.tsx' web/packages/agenta-ui/src -x sh -c 'printf "\n### %s\n" "$1"; sed -n "1,90p" "$1"' sh {}

printf '%s\n' '--- trigger declarations and call sites ---'
rg -n -C 5 'function (DropdownMenuTrigger|PopoverTrigger)|TooltipTrigger|SimpleTooltip' \
  web/packages/agenta-ui/src/components/ui \
  web/packages/agenta-ui/src/InfiniteVirtualTable/{columns/createStandardColumns.tsx,components/ColumnVisibilityTrigger.tsx,components/columnVisibility/TableSettingsDropdown.tsx}

Repository: Agenta-AI/agenta

Length of output: 8043


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for f in \
  web/packages/agenta-ui/src/components/ui/tooltip-composed.tsx \
  web/packages/agenta-ui/src/components/ui/tooltip.tsx \
  web/packages/agenta-ui/src/components/ui/popover.tsx \
  web/packages/agenta-ui/src/components/ui/dropdown-menu.tsx \
  web/packages/agenta-ui/src/components/ui/button.tsx
do
  if [ -f "$f" ]; then
    printf '\n### %s\n' "$f"
    cat -n "$f" | sed -n '1,180p'
  fi
done

printf '\n--- resolved React versions in lockfiles ---\n'
rg -n -C 2 '(^|/)react(@|:)|react-dom(@|:)|`@radix-ui/react-`(tooltip|popover|dropdown-menu)' \
  web/pnpm-lock.yaml web/**/package.json 2>/dev/null | head -240 || true

printf '\n--- all local trigger wrapper definitions ---\n'
rg -n -C 3 'function (DropdownMenuTrigger|PopoverTrigger)|const (DropdownMenuTrigger|PopoverTrigger)' \
  web/packages/agenta-ui/src web/packages 2>/dev/null | head -160 || true

Repository: Agenta-AI/agenta

Length of output: 40157


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

root = Path("web/packages/agenta-ui")
package = (root / "package.json").read_text()
popover = (root / "src/components/ui/popover.tsx").read_text()
dropdown = (root / "src/components/ui/dropdown-menu.tsx").read_text()
sites = [
    root / "src/InfiniteVirtualTable/components/ColumnVisibilityTrigger.tsx",
    root / "src/InfiniteVirtualTable/columns/createStandardColumns.tsx",
    root / "src/InfiniteVirtualTable/components/columnVisibility/TableSettingsDropdown.tsx",
]

peer_supports_react18 = bool(re.search(r'"react"\s*:\s*">=18\.0\.0"', package))
wrappers_forward_refs = {
    "PopoverTrigger": "forwardRef" in popover and "function PopoverTrigger" not in popover,
    "DropdownMenuTrigger": "forwardRef" in dropdown and "function DropdownMenuTrigger" not in dropdown,
}
print(f"agenta-ui peer supports React 18: {peer_supports_react18}")
for name, value in wrappers_forward_refs.items():
    print(f"{name} forwards a ref: {value}")

for path in sites:
    text = path.read_text()
    uses = ("<SimpleTooltip" in text and
            ("<PopoverTrigger asChild>" in text or "<DropdownMenuTrigger asChild>" in text))
    print(f"{path}: composes SimpleTooltip with a local trigger wrapper: {uses}")
PY

Repository: Agenta-AI/agenta

Length of output: 720


Forward refs through composed tooltip triggers.

agenta-ui supports React 18, but PopoverTrigger and DropdownMenuTrigger do not forward refs. In React 18, SimpleTooltip cannot pass its trigger ref to the underlying button. Update both shared wrappers to use React.forwardRef; this fixes all three affected call sites.

📍 Affects 3 files
  • web/packages/agenta-ui/src/InfiniteVirtualTable/components/ColumnVisibilityTrigger.tsx#L116-L120 (this comment)
  • web/packages/agenta-ui/src/InfiniteVirtualTable/columns/createStandardColumns.tsx#L587-L605
  • web/packages/agenta-ui/src/InfiniteVirtualTable/components/columnVisibility/TableSettingsDropdown.tsx#L133-L145

Comment on lines +38 to +44
<p
className={cn(
"mb-0 text-colorTextSecondary",
maxWidthClass,
"line-clamp-2 h-10",
className,
)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reset the native paragraph top margin.

Line 40 resets only the bottom margin. The native p top margin returns because this app disables Tailwind preflight. This adds vertical space before every table description.

Proposed fix
-                "mb-0 text-colorTextSecondary",
+                "m-0 text-colorTextSecondary",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<p
className={cn(
"mb-0 text-colorTextSecondary",
maxWidthClass,
"line-clamp-2 h-10",
className,
)}
<p
className={cn(
"m-0 text-colorTextSecondary",
maxWidthClass,
"line-clamp-2 h-10",
className,
)}

ardaerzin added a commit that referenced this pull request Aug 13, 2026
Diagnosed but not fixed. The console stack shows composeRefs recursing through
setRef into dispatchSetState, which is a composed ref callback rebuilt every
render, not a data problem. Prime suspect is the nested asChild pair in
ColumnVisibilityTrigger — SimpleTooltip around PopoverTrigger, both collapsing
onto one button — which CodeRabbit independently flagged on #5961.

The plan leads with confirming the diagnosis in a unit test before touching
anything, since a stack trace is a hypothesis, and records the trap that the
component throws a TypeError without a controls prop, which reads like a pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend refactoring A code change that neither fixes a bug nor adds a feature size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant