feat(app): hover hint and native link affordance for dashboard table tile row click#2321
feat(app): hover hint and native link affordance for dashboard table tile row click#2321alex-fedotyev wants to merge 3 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: 19c0204 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
🟡 Tier 3 — StandardIntroduces new logic, modifies core functionality, or touches areas with non-trivial risk. Why this tier:
Review process: Full human review — logic, architecture, edge cases. Stats
|
E2E Test Results✅ All tests passed • 178 passed • 3 skipped • 1195s
Tests ran across 4 shards in parallel. |
Deep Review🟡 P2 -- recommended
🔵 P3 nitpicks (8)
Reviewers (9): correctness, testing, maintainability, project-standards, adversarial, kieran-typescript, julik-frontend-races, agent-native, learnings-researcher. Testing gaps:
|
|
Pushed aa16b21d addressing the deep-review findings. P0 fix: failure rows now render as a real P2 fixes:
Smaller cleanups picked up along the way:
Screenshots in the description show the hover hint working on both search and dashboard targets, in light and dark theme. |
pulpdrew
left a comment
There was a problem hiding this comment.
LGTM, with a few suggestions
| // notification toast on left-click; the proper "muted row | ||
| // + warning icon" preempt state is tracked as AC8. |
There was a problem hiding this comment.
nit - comments tied to specific prompts are just clutter
| // notification toast on left-click; the proper "muted row | |
| // + warning icon" preempt state is tracked as AC8. | |
| // notification toast on left-click; |
|
Done in dd50d56 (removed the internal AC tracking note from the button fallback comment, per your suggestion). |
…tile row click When a dashboard table tile is configured with an `onClick` action (search or dashboard link), the row click destination is now visible before the user clicks. After ~250ms of hover, a small card appears with text like `Search HyperDX Logs` or `Open dashboard "API Latency Drilldown"`. The cell wrapper switches from a manual `<div role="link">` with hand-rolled cmd-click / middle-click / Enter handlers to a Next.js `<Link href>`. The browser now handles cmd-click and middle-click opening in a new tab natively, right-click shows "Open in New Tab" / "Copy Link Address" in the context menu, the destination URL appears in the status bar on hover, and keyboard users can Tab to a cell and press Enter to navigate with a visible focus ring. The cell wrapper now mirrors the pattern in `DBListBarChart.tsx` (the only other dashboard chart with a row drilldown HoverCard). A new `describeOnClick` helper in common-utils renders the one-line hint. The hook returns the description alongside the URL so future hint surfaces (chart-header subtitle, scope preview) can reuse the same string.
P0 fix:
- Failure rows now render as <button type="button"> instead of
<a href="#">. The previous anchor exposed cmd-click, middle-click,
and right-click "Open in New Tab" against a # fragment, which the
React onClick handler couldn't preventDefault on (auxclick doesn't
fire click). A real button has no native navigation, so those code
paths now do nothing for failure rows and the error toast still
fires on left-click.
P2 fixes:
- The HoverCard now wraps the whole <tr> in the body loop instead
of mounting one HoverCard per cell. Hovering anywhere on the row
shows a stable hint; cursor movement between cells no longer
flickers a different dropdown per column.
- getRowAction is now computed once per row and the hook caches by
row reference (WeakMap). The handlebars + URLSearchParams build
no longer reruns for every cell on every render.
- <Link> now uses prefetch={false}. Virtualized scroll no longer
triggers an N-row prefetch storm against /search? and /dashboards
routes the user usually never opens in bulk.
- Added a component-level test (HDXMultiSeriesTableChart.test.tsx)
that exercises both success and failure branches end to end:
asserts the anchor / button shape, the onClickError wiring, the
row-level HoverCard hint visibility, and the legacy
getRowSearchLink fallback.
Smaller cleanups:
- describeOnClick now does an explicit exhaustiveness check on the
OnClick discriminator so adding a third variant fails type-check.
- onClickError is typed as React.MouseEvent<HTMLButtonElement>.
- The cell wrapper carries data-testid="dashboard-table-row-action"
on both branches; e2e page object resolves by testid so future
inline column links don't steal the click.
- Hook test asserts URL params via URLSearchParams instead of
position-coupled regex.
dd50d56 to
5def143
Compare
…re rows Addresses three rendering issues Drew flagged on #2321 after approval: - Failure rows now share a single .cellButton SCSS reset with the success-row <Link>, so the cell wrapper renders identically across branches. The user-agent button defaults (padding, font, color, text-align, line-height) were leaking through. - Hover hint is suppressed when action.url === null. The previous state showed an "Open in search" hint on a row whose click would only fire an error toast, which lied to the user. - Row-level HoverCard (position="top") replaced with Tooltip.Floating wrapping the <tr>. The hint now follows the cursor at the cell rather than anchoring at row-center-top. Tests updated: the failure-row hint test now asserts the hint is absent; a success-row positive test was added. Both branches get a data-shape attribute so the test assertions don't couple to the CSS-module hash.
|
Fixed in 19c0204e:
One quirk to flag: Mantine v9's Also re-applied the comment cleanup from ci-lint + ci-unit + knip green locally. |


Summary
When a dashboard table tile is configured with an
onClickaction (#2140, #2141, #2146, #2148), the row click destination is now discoverable before the user commits to the click.What's new for users:
Search HyperDX LogsorOpen dashboard "API Latency Drilldown"(or genericOpen in search/Open dashboardwhen the target is templated or the named source / dashboard no longer exists).<a href>. Cmd-click opens the destination in a new tab, middle-click opens it in a new tab, right-click shows the browser context menu with "Open in New Tab" and "Copy Link Address", and the destination URL appears in the status bar on hover.Screenshots
Search action: hovering a row reveals the resolved source name.
Dashboard action: hovering a row reveals the resolved dashboard name.
How the implementation changes:
packages/app/src/HDXMultiSeriesTableChart.tsx: cell wrapper goes from<div role="link" tabIndex={0}>plus manualonClick/onAuxClick/onMouseDown/onKeyDownhandlers to a Next.js<Link href>withprefetch={false}. The HoverCard wraps the whole<tr>at the row body level so the hint position stays stable as the cursor moves across cells; cell-level mounting would flicker per column. Rows whose templates fail to resolve render as a real<button type="button">(not<a href="#">) so cmd-click / middle-click / right-click "Open in New Tab" can't silently open a meaningless new tab against a#fragment.packages/app/src/components/DBTableChart.tsx: drops the parentonRowClickcmd/middle-click branching; threads newgetRowAction(or legacygetRowSearchLink) into Table.packages/common-utils/src/core/linkUrlBuilder.ts: newdescribeOnClick({ onClick, sourceNamesById, dashboardNamesById }): stringhelper returns the one-line hint, with an exhaustiveness check on the OnClick discriminator.packages/app/src/hooks/useOnClickLinkBuilder.ts: also buildsMap<id, name>for sources and dashboards, computes the row-independent description once, and returns a per-row resolver of shape{ url, description, onClickError? }. Per-row results are memoized internally (WeakMap) so cells sharing a row don't rerun handlebars rendering. When a row's templates fail to resolve,urlisnullandonClickErrorfires the existing Mantine "Link error" toast on click.styles/focus.module.scssfocusRingstyle.data-testid="dashboard-table-row-action"on both branches; the e2e page object resolves by testid so future inline column links don't steal the click.getRowSearchLinkdrilldown path (used outside dashboards, e.g. the services dashboard) renders as a plain<Link href>without a HoverCard so behavior there is unchanged.Test plan
make ci-lintclean across all 3 workspaces.make ci-unitclean. NewHDXMultiSeriesTableChartcomponent test covers both success and failure branches end to end: anchor / button shape,onClickErrorwiring, row-level HoverCard hint visibility, legacygetRowSearchLinkfallback.describeOnClickunit tests cover all 6 OnClickSchema discriminator + name-lookup combinations.useOnClickLinkBuilderhook tests cover: no onClick configured returns null, resolved source name in description, resolved dashboard name in description, row resolution failure encodes asurl: null+ click handler fires notification, WeakMap caching shares results across cells of the same row.knipclean (no new unused exports).<button>) shows no status bar URL and clicking fires the existing redLink errortoast. Right-click on a success anchor shows the native context menu; cmd-click and middle-click open in a new tab.