Skip to content

feat(app): filters sidebar for multi-source search - #2865

Draft
teeohhem wants to merge 1 commit into
tom/multi-source-searchfrom
tom/multi-source-filters
Draft

feat(app): filters sidebar for multi-source search#2865
teeohhem wants to merge 1 commit into
tom/multi-source-searchfrom
tom/multi-source-filters

Conversation

@teeohhem

Copy link
Copy Markdown
Contributor

Summary

Stacked on #2862 — review that first; this PR's diff is relative to tom/multi-source-search.

Multi-source search shipped without the filters sidebar, because everything about it was single-source: facets come from one table's field list and value queries, and applied filters are SQL predicates naming one table's columns. This PR brings the sidebar back for multi-source searches with cross-source semantics.

Each selected source runs its own facet pipeline (the existing useFetchFacets, one hook slot per source), and a new lean MultiSourceSearchFilters sidebar merges the results by field path with values unioned, reusing the single-source FilterGroup/NestedFilterGroup rendering. Checking a value applies the filter to every source that has the field. The key semantic decision: a source whose table lacks a filtered column is excluded from the search with a visible reason on its status chip (a quiet filter-off icon plus tooltip), rather than silently returning rows that ignore the filter or erroring the whole search. Filter pills and add-to-filter from the row side panel are re-enabled in multi mode; filter-key escaping and date-column detection now run against the union of the selected sources' schemas.

Single-source-only affordances (pins, shared filters, value counts, load-more, analysis-mode tabs, denoising) are intentionally absent from the multi sidebar for now. Single-source behavior is unchanged.

Screenshots or video

Verified live against the demo stack: a two-source (logs + traces) search shows merged facet groups (LogAttributes, SpanAttributes, SeverityText, StatusCode, ...); filtering ServiceName = cart narrows both sources; filtering trace-only StatusCode = Unset excludes the log source with the chip reason. Screenshots can be dragged in from the local capture set.

How to test on Vercel preview

Preview routes: /search

Steps:

  1. Open /search and wait for search result rows to appear.
  2. Click the "+" button next to the source selector (data-testid "add-search-source").
  3. Click the sources multi-select (data-testid "source-multi-selector") and select "Demo Traces" in the dropdown, then press Escape to close the dropdown.
  4. Wait for the Filters panel on the left to list field groups from both sources (for example "LogAttributes", "SpanAttributes", "ServiceName", "StatusCode") — this can take up to 30 seconds.
  5. Click the "StatusCode" filter group to expand it, then click its first value checkbox and wait a few seconds for the search to re-run.
  6. Verify the results table now shows only "Demo Traces" rows, and the "Demo Logs" status chip above the table is dimmed with a filter icon explaining it is excluded because it doesn't have StatusCode.

Compound Engineering
Claude Code

The filters sidebar now works across a multi-source selection. Each
selected source runs its own facet pipeline (fields + values); the
sidebar merges them by field path with values unioned, reusing the
single-source FilterGroup rendering. Checking a value filters every
source that has the field.

A source whose table lacks a filtered column is excluded from the
search with a visible reason on its status chip, rather than silently
returning rows that ignore the filter. Filter pills and add-to-filter
from the row side panel are re-enabled in multi mode, with filter-key
escaping and date-column detection driven by the union of the selected
sources' schemas.
@changeset-bot

changeset-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 667dfb1

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 Minor
@hyperdx/api Minor
@hyperdx/otel-collector Minor

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

vercel Bot commented Aug 11, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
hyperdx-oss Ready Ready Preview Aug 11, 2026 4:12pm
hyperdx-storybook Ready Ready Preview Aug 11, 2026 4:12pm

Request Review

@greptile-apps

greptile-apps Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR restores the filters sidebar for multi-source search by merging per-source facets and excluding sources that cannot satisfy an active filter.

  • Adds merged multi-source facet rendering and filter controls.
  • Applies filters to row and histogram query specifications and displays exclusion reasons on source chips.
  • Extends multi-source schema metadata with date-column and filter-column resolution.
  • Adds focused unit coverage for filter-root and per-source column resolution.

Confidence Score: 4/5

The facet pipeline should be fixed before merging because it still queries sources explicitly excluded for missing active-filter columns.

Row and histogram queries honor each source's disabled reason, but the new facet slot only checks whether a spec exists, allowing an excluded source's active filter key to reach its facet request and invalidate that source's facet batch.

Files Needing Attention: packages/app/src/components/MultiSourceSearchFilters.tsx

Important Files Changed

Filename Overview
packages/app/src/DBSearchPage.tsx Coordinates multi-source schema metadata, filter resolution, query specs, filter pills, and sidebar rendering; excluded sources remain represented in facet specs.
packages/app/src/components/MultiSourceSearchFilters.tsx Adds merged facet rendering, but its query slot ignores source exclusion and the new component exceeds the repository's file-size limit.
packages/app/src/components/MultiSourceRowTable.tsx Correctly suppresses excluded source queries and presents their filter-related status.
packages/app/src/components/MultiSourceTimeChart.tsx Correctly suppresses histogram queries for excluded sources.
packages/app/src/hooks/useMultiSourceSearch.ts Adds date-column unions and root-column resolution with focused unit tests.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Filters[Active filters] --> Resolve[Resolve filter columns per source]
  Resolve -->|Column present| Specs[Build row and histogram specs]
  Resolve -->|Column absent| Disabled[Attach disabled reason]
  Specs --> Rows[Run row query]
  Specs --> Histogram[Run histogram query]
  Specs --> Facets[Run facet pipeline]
  Disabled -. correctly blocks .-> Rows
  Disabled -. correctly blocks .-> Histogram
  Disabled -. currently does not block .-> Facets
  Facets --> Sidebar[Merge facets into sidebar]
Loading

Fix All in Claude Code Fix All in Conductor Fix All in Cursor Fix All in Codex

Reviews (1): Last reviewed commit: "feat(app): filters sidebar for multi-sou..." | Re-trigger Greptile

// Value lists show everything in range (not narrowed by the current
// query), matching the sidebar's default "show all values" behavior.
mode: 'all',
filterState,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Excluded sources still fetch facets

When an active filter references a column absent from one selected source, the row and histogram pipelines disable that source but useSourceFacetsSlot still fetches its active filter key. The resulting missing-column request invalidates that source's facet batch, leaving the merged sidebar incomplete, empty, or displaying stale loading activity.

Knowledge Base Used: App Components and Charts

Fix in Claude Code Fix in Conductor Fix in Cursor Fix in Codex

</ScrollArea>
</Box>
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Sidebar exceeds component size limit

The new component is 315 lines, exceeding the repository's 300-line limit and coupling facet queries, facet merging, resizing, and rendering in one file. Extracting part of this logic would reduce the maintenance cost of subsequent filter changes.

Context Used: AGENTS.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code Fix in Conductor Fix in Cursor Fix in Codex

@teeohhem

Copy link
Copy Markdown
Contributor Author

Superseded by #2869, which contains these commits and additionally makes the N-ary pipeline the single search path (one source is just N=1), removing the separate single-source results table from the search page. Leaving this open for reference; suggest closing once #2869 is reviewed.

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.

1 participant