feat(app): hover hint and native link affordance for dashboard table tile row click#2321
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: a664160 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 • 191 passed • 3 skipped • 1216s
Tests ran across 4 shards in parallel. |
Deep ReviewThis PR is a UI-affordance change touching ~600 LOC across a table component, a hook, a helper, and tests. No auth, data, or migration code. After dedup, cross-reviewer corroboration, and default-down regrading, there are no concrete P0/P1 failure modes introduced by the diff — the issues cluster around missing tests for the headline behaviors and several P3 polish items. ✅ No critical issues found. 🟡 P2 -- recommended
🔵 P3 nitpicks (12)
Reviewers (11): correctness, testing, maintainability, project-standards, agent-native, learnings-researcher, adversarial, julik-frontend-races, kieran-typescript, api-contract, reliability. 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). |
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. |
| prefetch={false} | ||
| className={interactiveClassName} | ||
| data-testid="dashboard-table-row-action" | ||
| data-shape="link" |
There was a problem hiding this comment.
This seems pretty unnecessary. If the tests are already asserting on the element type, this is just saying the same thing as the element type (link or button).
…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.
19c0204 to
4aebdb7
Compare
|
Rebased onto current main (commit Net change vs the previous tip on that file is the same single hunk you reviewed; everything else is just trailing main forward. Local checks pass: |
…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.
…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.
4aebdb7 to
4af8aa3
Compare


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.