Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/multi-source-filters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@hyperdx/app': minor
---

The filters sidebar now works when searching multiple sources. Facet fields
and values merge across the selected sources, and checking a value filters
every source that has the field. A source whose table lacks a filtered column
is excluded from the results with a visible reason on its status chip instead
of silently returning unfiltered rows. Filter pills and add-to-filter from the
row side panel work in multi-source mode too.
393 changes: 245 additions & 148 deletions packages/app/src/DBSearchPage.tsx

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion packages/app/src/components/DBSearchPageFilters/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ export function useFetchFacets({
filterState,
showMoreFields,
disableValues,
enabled = true,
}: {
chartConfig: BuilderChartConfigWithDateRange;
sourceId: string | null;
Expand All @@ -262,6 +263,8 @@ export function useFetchFacets({
filterState?: FilterState;
showMoreFields?: boolean;
disableValues?: boolean;
/** Disable all data fetching (e.g. an unused multi-source hook slot). */
enabled?: boolean;
}) {
const facetsQuery = useFacets({
chartConfig,
Expand All @@ -270,7 +273,7 @@ export function useFetchFacets({
dateRange,
filterState,
showMoreFields,
enabled: true,
enabled,
disableValues,
});

Expand Down
30 changes: 26 additions & 4 deletions packages/app/src/components/MultiSourceRowTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
TSource,
} from '@hyperdx/common-utils/dist/types';
import { Flex, Group, Loader, Text, Tooltip } from '@mantine/core';
import { IconAlertTriangle } from '@tabler/icons-react';
import { IconAlertTriangle, IconFilterOff } from '@tabler/icons-react';

import api from '@/api';
import { searchChartConfigDefaults } from '@/defaults';
Expand All @@ -41,6 +41,11 @@ import { getMultiSourceColor, SourceBadge } from './MultiSourceBadge';
export type MultiSourceStreamSpec = {
source: TSource;
config: BuilderChartConfigWithDateRange;
/**
* When set, the source doesn't run at all (e.g. an active filter references
* a column its table lacks); shown on the source's status chip.
*/
disabledReason?: string;
};

// Placeholder config for unused hook slots. The metadata hooks inside
Expand Down Expand Up @@ -109,7 +114,11 @@ function useSourceStream(

const { data, fetchNextPage, hasNextPage, isFetching, isError, error } =
useOffsetPaginatedQuery(mergedConfig ?? configWithDefaults, {
enabled: enabled && spec != null && mergedConfig != null,
enabled:
enabled &&
spec != null &&
spec.disabledReason == null &&
mergedConfig != null,
isLive,
queryKeyPrefix,
enableSmallFirstWindow,
Expand Down Expand Up @@ -177,10 +186,23 @@ function StreamStatusChips({ streams }: { streams: SourceStream[] }) {
{streams.map((stream, i) => {
if (stream.spec == null) return null;
const name = stream.spec.source.name;
const disabledReason = stream.spec.disabledReason;
return (
<Group key={stream.spec.source.id} gap={4} wrap="nowrap">
<Group
key={stream.spec.source.id}
gap={4}
wrap="nowrap"
style={disabledReason != null ? { opacity: 0.55 } : undefined}
>
<SourceBadge name={name} color={getMultiSourceColor(i)} />
{stream.isFetching && <Loader size={10} color="gray" />}
{disabledReason != null && (
<Tooltip label={disabledReason} multiline maw={420}>
<Text component="span" c="dimmed" lh={1}>
<IconFilterOff size={13} />
</Text>
</Tooltip>
)}
{stream.isError && (
<Tooltip
label={`${name} failed to load and is excluded from these results: ${
Expand Down Expand Up @@ -258,7 +280,7 @@ export default function MultiSourceRowTableWithSidebar({
window: stream.data?.window ?? null,
lastPageRowCount: stream.data?.lastPageRowCount ?? null,
hasNextPage: stream.hasNextPage,
isActive: !stream.isError,
isActive: !stream.isError && stream.spec.disabledReason == null,
dateRange: stream.spec.config.dateRange,
})),
[streams],
Expand Down
Loading