Skip to content

feat: filter/exclude/copy actions on attribute values#1850

Open
alex-fedotyev wants to merge 6 commits intomainfrom
event-deltas/filter-actions
Open

feat: filter/exclude/copy actions on attribute values#1850
alex-fedotyev wants to merge 6 commits intomainfrom
event-deltas/filter-actions

Conversation

@alex-fedotyev
Copy link
Contributor

@alex-fedotyev alex-fedotyev commented Mar 5, 2026

Summary

Closes #1829

Adds interactive filter/exclude/copy actions to the Event Deltas attribute comparison charts:

  • Click popover on chart bars: Clicking a bar in any PropertyComparisonChart opens a popover with the attribute name, value, and Selection/Background percentages, plus action buttons.
  • Filter/Exclude buttons: Use the existing search sidebar filter system (setFilterValue) to include or exclude an attribute value from results. After applying a filter, the heatmap selection is automatically cleared.
  • Copy button: Copies the raw attribute value to the clipboard.
  • Key conversion utilities: New flattenedKeyToSqlExpression and flattenedKeyToFilterKey functions convert dot-notation property keys (produced by flattenData()) into ClickHouse bracket notation for Map columns (e.g., ResourceAttributes.service.name -> ResourceAttributes['service.name']), enabling correct filter integration.

Changes

  • deltaChartUtils.ts -- Added escapeRegExp, flattenedKeyToSqlExpression, flattenedKeyToFilterKey, and AddFilterFn type
  • PropertyComparisonChart.tsx -- Added click handler, popover with Filter/Exclude/Copy actions using createPortal
  • DBDeltaChart.tsx -- Added onAddFilter prop, handleAddFilter callback wrapping key conversion, re-exported AddFilterFn
  • DBSearchHeatmapChart.tsx -- Added onAddFilter prop, handleAddFilterAndClearSelection callback
  • DBSearchPage.tsx -- Passed searchFilters.setFilterValue as onAddFilter to DBSearchHeatmapChart
  • New test file deltaChartFilterKeys.test.ts with 16 tests for key conversion functions

Test plan

  • 16 unit tests for flattenedKeyToSqlExpression and flattenedKeyToFilterKey (Map columns, Array(Map) columns, simple columns, LowCardinality wrappers, SQL injection escaping)
  • All 57 existing delta chart tests still pass
  • ESLint passes with no errors
  • Manual: click a bar in the delta chart -> popover appears with correct value and percentages
  • Manual: click Filter button -> sidebar filter is applied, heatmap selection clears
  • Manual: click Exclude button -> exclusion filter is applied
  • Manual: click Copy button -> value copied to clipboard, button shows checkmark

🤖 Generated with Claude Code

Add click-to-action popover on PropertyComparisonChart bars with
Filter, Exclude, and Copy buttons. Implement flattenedKeyToSqlExpression
and flattenedKeyToFilterKey utilities to convert dot-notation property
keys (from flattenData) into ClickHouse bracket notation for Map columns,
enabling correct filter integration with the search sidebar.

Wire onAddFilter through DBDeltaChart -> DBSearchHeatmapChart ->
DBSearchPage, clearing heatmap selection after applying a filter.

Closes #1829

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Mar 5, 2026

🦋 Changeset detected

Latest commit: 5855a2a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@hyperdx/app Patch
@hyperdx/api Patch
@hyperdx/otel-collector Patch

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

@vercel
Copy link

vercel bot commented Mar 5, 2026

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

Project Deployment Actions Updated (UTC)
hyperdx-oss Ready Ready Preview, Comment Mar 5, 2026 4:58pm

Request Review

@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Claude finished @alex-fedotyev's task in 1m 29s —— View job


PR Review

Good feature addition with solid test coverage. A few minor issues to address:

  • ⚠️ PropertyComparisonChart.tsx:336-341setTimeout without cleanup: The setTimeout(() => setCopiedValue(false), 2000) in an async onClick has no clearTimeout cleanup. If the component unmounts within 2s of clicking copy, React will log a state-update-on-unmounted-component warning. Store the timeout ID and cancel it in a useEffect cleanup or on component unmount. Fix this →

  • ⚠️ PropertyComparisonChart.tsx:269 — Popover may render off-screen: The popover is positioned at clientY - 8 with transform: translate(-50%, -100%) (renders above click point) and clientX with no viewport boundary clamping. Clicking a bar near the top or sides of the viewport will push the popover outside the visible area. Consider clamping left/top to viewport bounds.

  • ℹ️ deltaChartUtils.ts:222-242flattenedKeyToFilterKey is functionally identical to flattenedKeyToSqlExpression: The Map branch is duplicated verbatim, and the Array(Map) branch just delegates to flattenedKeyToSqlExpression. If the two functions will never diverge, consider having one call the other (or merging them). If they're intentionally separate for future divergence, a comment explaining the intended difference would help.

✅ Key conversion logic is correct and well-tested (SQL injection escaping, 0→1-based index conversion, LowCardinality wrapper stripping). The portal-based popover approach and outside-click dismissal are solid.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

E2E Test Results

All tests passed • 86 passed • 3 skipped • 905s

Status Count
✅ Passed 86
❌ Failed 0
⚠️ Flaky 2
⏭️ Skipped 3

Tests ran across 4 shards in parallel.

View full report →

Store timeout ID in a ref and clear it on unmount to avoid
setCopiedValue firing after component is unmounted.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Claude finished @alex-fedotyev's task in 36s —— View job


PR Review

✅ The setTimeout cleanup issue flagged in the previous review has already been fixed (commit e46b7e5a) — copyTimeoutRef with useEffect cleanup is correctly implemented.

Two remaining minor items:

  • ⚠️ PropertyComparisonChart.tsx:269-278 — Popover clips at viewport edges: The portal renders at clientX, clientY - 8 with transform: translate(-50%, -100%) but no boundary clamping. Clicking a bar near the top or right edge will push the popover off-screen. Consider clamping left to [popoverWidth/2, window.innerWidth - popoverWidth/2] and falling back to rendering below the click point when near the top.

  • ℹ️ deltaChartUtils.ts:222-242flattenedKeyToFilterKey duplicates flattenedKeyToSqlExpression: The Map branch is identical; the Array(Map) branch just delegates back. Consider having flattenedKeyToFilterKey call flattenedKeyToSqlExpression directly (they currently produce the same output) or add a comment explaining if/when they're expected to diverge.

No critical bugs or security issues. The key conversion logic, SQL-injection escaping, and test coverage are solid.

- Clamp popover left position to keep it within viewport edges
- Flip popover below click point when near the top of the viewport
- Add comment explaining why flattenedKeyToFilterKey is intentionally
  separate from flattenedKeyToSqlExpression (future divergence)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Claude finished @alex-fedotyev's task in 23s —— View job


PR Review

✅ No critical issues found.

The two previously flagged items are addressed:

  • setTimeout cleanup: fixed via copyTimeoutRef with useEffect cleanup (e46b7e5a)
  • Viewport clamping: fixed via Math.max(160, Math.min(..., window.innerWidth - 160)) and flip-below logic (89e5ed95)
  • flattenedKeyToFilterKey duplication: a comment was added at line 222–224 explaining the intentional separation for future divergence — acceptable

Code is clean, tests are solid, no security issues or project pattern violations.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Claude finished @alex-fedotyev's task in 22s —— View job


PR Review

✅ No critical issues found.

All previously flagged items have been resolved:

  • setTimeout cleanup: fixed via copyTimeoutRef with useEffect
  • Viewport clamping: fixed with Math.max/Min bounds and flip-below logic
  • flattenedKeyToFilterKey duplication: comment added explaining intentional separation

Code is clean, tests are solid, no security issues or pattern violations.

Set allowEscapeViewBox x to false so Recharts keeps the tooltip within
the chart's horizontal bounds. Vertical escape remains enabled for
tall tooltips.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Claude finished @alex-fedotyev's task in 20s —— View job


PR Review

✅ No critical issues found.

All previously flagged items have been resolved:

  • setTimeout cleanup: fixed via copyTimeoutRef with useEffect
  • Viewport clamping: fixed with Math.max/Min bounds and flip-below logic
  • flattenedKeyToFilterKey duplication: comment added explaining intentional separation

Code is clean, tests are solid, no security issues or pattern violations.

@alex-fedotyev alex-fedotyev requested review from a team and karl-power and removed request for a team March 5, 2026 15:40
@kodiakhq
Copy link
Contributor

kodiakhq bot commented Mar 5, 2026

This PR currently has a merge conflict. Please resolve this and then re-add the automerge label.

@kodiakhq kodiakhq bot removed the automerge label Mar 5, 2026
Resolve conflicts: keep both onAddFilter (filter-actions) and
spanIdExpression (sampling, merged via #1849) props.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@alex-fedotyev alex-fedotyev marked this pull request as ready for review March 5, 2026 17:04
@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Claude finished @alex-fedotyev's task in 50s —— View job


PR Review

✅ No critical issues found.

All previously flagged items have been resolved:

  • setTimeout cleanup: fixed via copyTimeoutRef with useEffect
  • Viewport clamping: fixed with Math.max/Min bounds and flip-below logic
  • flattenedKeyToFilterKey duplication: comment added explaining intentional separation

One minor style nit: DBDeltaChart.tsx has export type { AddFilterFn } sandwiched between two separate import blocks from ./deltaChartUtils (lines 21–36). ES modules require export statements to be at the top level but not interspersed between imports — this works but is unconventional. Consider consolidating the two deltaChartUtils import statements into one block and moving the re-export above or below them.

Everything else looks clean — filter key conversion, SQL injection escaping, test coverage, and portal-based popover dismissal are all solid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Event Deltas: Filter/Exclude/Copy actions on attribute values

1 participant