fix(web): clamp agents table cells and stop drag-reorder reshuffle

Merged
DE
2d ago
+123-43

Description

These are fixes to the admin Agents table (AgentsTable), plus a new opt-in column option in @opal/Table.

1. Text overflow. Long names and descriptions wrapped past the fixed row height and overlapped the next row.

  • The Name and Description cells now use @opal/OverflowText in place of the legacy refresh-components Text. The text is clamped to 1 line. When the text is cut, hover it to see the full text in a tooltip.
  • The Content cells now clamp to 1 line. Created By sets titleMaxLines={1}. Access sets titleMaxLines={1} and descriptionMaxLines={1}.
  • @opal/Table data columns get a new option, truncate?: boolean. When it is set, TableCell adds w-0 min-w-full to .tbl-cell-inner. Under table-layout: auto, the content then cannot widen the column, so long content truncates. Before this change, the Agents table grew to 2844px inside an 840px container. All Agents data columns set truncate: true. The option is off by default, so other tables do not change. For example, the Users GroupsCell measures its own width and needs the old behavior.

2. Random reshuffle after a drag-reorder. The causes:

  • GET /api/admin/persona (get_persona_snapshots_for_user) has no ORDER BY, so the refetch after a save came back in arbitrary DB order.
  • handleReorder sent only the moved range, as indexes into the visible list. Other agents kept null or stale priorities, which collided with the new values.
  • The row snapped back until the refetch finished.

The fix:

  • The table sorts agents client-side the way the paginated endpoint does: display_priority ascending with nulls last, then |id|.
  • buildDisplayPriorityMap merges the reordered visible IDs back into the full agent list. It then sends a priority for every agent whose position changed.
  • The new priorities go into the SWR cache before the PATCH.
  • @opal/Table now passes the query-filtered rows to useDraggableRows, not all items. A drag while a search is active no longer shifts hidden rows.

How Has This Been Tested?

  • bun run types:check, oxlint, oxfmt and the @opal/Table jest tests pass.
  • I tested in the browser on a local stack with 8 agents; see the comment below. The checks were: no horizontal overflow at 840px and 1600px, ellipsis plus hover tooltip on long cells, and normal, far-below and search-filtered drags. Each order persisted across reload and matched the DB priorities.

Additional Options

  • [Optional] Please cherry-pick this PR to the latest release version.

Link to Devin session: https://app.devin.ai/sessions/0d13205be9bb4560a7a0e55e880edd52
Open in Devin Desktop: https://app.devin.ai/desktop/session/0d13205be9bb4560a7a0e55e880edd52?variant=devin


Summary by cubic

Fixes two bugs in the admin Agents table: long text no longer overlaps the next row, and rows stay put after a drag-reorder.

  • Data columns now accept an opt-in truncate flag; truncated columns never widen the column, clamp content to one line, and show the full value in a hover tooltip.
  • The Name, Description, Created By, and Access cells clamp this way, using OverflowText or one-line Content with max-line limits.
  • Drag-reorder operates on query-visible rows only, so hidden rows keep their positions.
  • On drop, the full agent list is renumbered from the new visible order and the priorities are written to the SWR cache before the PATCH, so rows don't snap back while saving; nothing is saved when no priority changed, and a failed save refreshes the table and shows an error.
  • The table sorts agents client-side to match the server's order (display_priority ascending with nulls last, then |id|).

Summary by CodeRabbit

  • New Features
    • Added text truncation for long agent names, descriptions, owners, and access details in tables.
    • Improved agent reordering, including consistent sorting and reliable updates when filtered.
  • Bug Fixes
    • Preserved correct row positions during drag-and-drop when table filters are active.
  • Documentation
    • Updated table documentation to describe the new truncation option.