mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
feat: Add Column toggle button to filter panel in DBSearchPage (#1947)
## Summary Adds a column toggle button (+ / - icon) next to the "Show Distribution" button in each filter group header on the search page. Clicking the button adds or removes the filter's field from the `SELECT` statement, and the table reflects the change immediately. ### Changes - **`FilterGroup`** (`DBSearchPageFilters.tsx`): Added `onColumnToggle` and `isColumnDisplayed` props. Renders an `ActionIcon` with `IconPlus` (add) or `IconMinus` (remove) between the distribution toggle and the pin field button. - **`NestedFilterGroup`**: Passes the new column toggle props through to child `FilterGroup` components. - **`DBSearchPage.tsx`**: Passes `toggleColumn` and `displayedColumns` to `DBSearchPageFilters`, reusing the existing `toggleColumn` callback that manages the `SELECT` form field. ### Screenshots or video | Before | After | | :----- | :---- | | Only distribution and pin buttons in filter header | New +/- column button appears between distribution and pin buttons | ### How to test locally or on Vercel 1. Navigate to the Search page 2. Open the filter panel on the left side 3. Find any filter group and hover over the header area — a `+` icon should appear next to the distribution chart icon 4. Click the `+` icon — the field should be added to the `SELECT` input and appear as a column in the results table 5. Click the `-` icon (now shown since the column is displayed) — the field should be removed from `SELECT` and the column disappears ### References - Linear Issue: HDX-3770 Linear Issue: [HDX-3770](https://linear.app/clickhouse/issue/HDX-3770/telstra-add-column-from-filter-panel-in-dbsearchpage) <div><a href="https://cursor.com/agents/bc-11d702b5-a58e-485c-982f-61d990e45091"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-11d702b5-a58e-485c-982f-61d990e45091"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div> Co-authored-by: Cursor Agent <199161495+cursoragent@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
b642ce43d3
commit
c9d1dda358
4 changed files with 59 additions and 1 deletions
5
.changeset/hdx-3770-column-from-filter-panel.md
Normal file
5
.changeset/hdx-3770-column-from-filter-panel.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@hyperdx/app": patch
|
||||
---
|
||||
|
||||
feat: Add column toggle button to filter panel in DBSearchPage
|
||||
|
|
@ -1769,6 +1769,8 @@ function DBSearchPage() {
|
|||
? searchedSource.durationExpression
|
||||
: undefined)
|
||||
}
|
||||
onColumnToggle={toggleColumn}
|
||||
displayedColumns={displayedColumns}
|
||||
{...searchFilters}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
|
|
|
|||
|
|
@ -36,8 +36,10 @@ import {
|
|||
IconChevronRight,
|
||||
IconChevronUp,
|
||||
IconFilterOff,
|
||||
IconMinus,
|
||||
IconPin,
|
||||
IconPinFilled,
|
||||
IconPlus,
|
||||
IconRefresh,
|
||||
IconSearch,
|
||||
IconShadow,
|
||||
|
|
@ -341,6 +343,8 @@ export type FilterGroupProps = {
|
|||
isPinned: (value: string | boolean) => boolean;
|
||||
onFieldPinClick?: VoidFunction;
|
||||
isFieldPinned?: boolean;
|
||||
onColumnToggle?: VoidFunction;
|
||||
isColumnDisplayed?: boolean;
|
||||
onLoadMore: (key: string) => void;
|
||||
loadMoreLoading: boolean;
|
||||
hasLoadedMore: boolean;
|
||||
|
|
@ -349,7 +353,7 @@ export type FilterGroupProps = {
|
|||
chartConfig: BuilderChartConfigWithDateRange;
|
||||
isLive?: boolean;
|
||||
onRangeChange?: (range: { min: number; max: number }) => void;
|
||||
distributionKey?: string; // Optional key to use for distribution queries, defaults to name
|
||||
distributionKey?: string;
|
||||
};
|
||||
|
||||
export const FilterGroup = ({
|
||||
|
|
@ -365,6 +369,8 @@ export const FilterGroup = ({
|
|||
onPinClick,
|
||||
onFieldPinClick,
|
||||
isFieldPinned,
|
||||
onColumnToggle,
|
||||
isColumnDisplayed,
|
||||
onLoadMore,
|
||||
loadMoreLoading,
|
||||
hasLoadedMore,
|
||||
|
|
@ -641,6 +647,29 @@ export const FilterGroup = ({
|
|||
)}
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
{onColumnToggle && (
|
||||
<Tooltip
|
||||
label={isColumnDisplayed ? 'Remove Column' : 'Add Column'}
|
||||
position="top"
|
||||
withArrow
|
||||
fz="xxs"
|
||||
color="gray"
|
||||
>
|
||||
<ActionIcon
|
||||
size="xs"
|
||||
variant="subtle"
|
||||
color="gray"
|
||||
onClick={onColumnToggle}
|
||||
data-testid={`toggle-column-button-${name}`}
|
||||
>
|
||||
{isColumnDisplayed ? (
|
||||
<IconMinus size={14} />
|
||||
) : (
|
||||
<IconPlus size={14} />
|
||||
)}
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
)}
|
||||
{onFieldPinClick && (
|
||||
<Tooltip
|
||||
label={isFieldPinned ? 'Unpin Field' : 'Pin Field'}
|
||||
|
|
@ -844,6 +873,8 @@ const DBSearchPageFiltersComponent = ({
|
|||
denoiseResults,
|
||||
setDenoiseResults,
|
||||
setFilterRange,
|
||||
onColumnToggle,
|
||||
displayedColumns,
|
||||
}: {
|
||||
analysisMode: 'results' | 'delta' | 'pattern';
|
||||
setAnalysisMode: (mode: 'results' | 'delta' | 'pattern') => void;
|
||||
|
|
@ -854,6 +885,8 @@ const DBSearchPageFiltersComponent = ({
|
|||
denoiseResults: boolean;
|
||||
setDenoiseResults: (denoiseResults: boolean) => void;
|
||||
setFilterRange: (key: string, range: { min: number; max: number }) => void;
|
||||
onColumnToggle?: (column: string) => void;
|
||||
displayedColumns?: string[];
|
||||
} & FilterStateHook) => {
|
||||
const setFilterValue = useCallback(
|
||||
(
|
||||
|
|
@ -1334,6 +1367,8 @@ const DBSearchPageFiltersComponent = ({
|
|||
isPinned={(key, value) => isFilterPinned(key, value)}
|
||||
onFieldPinClick={key => toggleFieldPin(key)}
|
||||
isFieldPinned={key => isFieldPinned(key)}
|
||||
onColumnToggle={onColumnToggle}
|
||||
displayedColumns={displayedColumns}
|
||||
onLoadMore={loadMoreFilterValuesForKey}
|
||||
loadMoreLoading={group.children.reduce(
|
||||
(acc, child) => {
|
||||
|
|
@ -1394,6 +1429,12 @@ const DBSearchPageFiltersComponent = ({
|
|||
isPinned={value => isFilterPinned(facet.key, value)}
|
||||
onFieldPinClick={() => toggleFieldPin(facet.key)}
|
||||
isFieldPinned={isFieldPinned(facet.key)}
|
||||
onColumnToggle={
|
||||
onColumnToggle
|
||||
? () => onColumnToggle(facet.key)
|
||||
: undefined
|
||||
}
|
||||
isColumnDisplayed={displayedColumns?.includes(facet.key)}
|
||||
onLoadMore={loadMoreFilterValuesForKey}
|
||||
loadMoreLoading={loadMoreLoadingKeys.has(facet.key)}
|
||||
hasLoadedMore={Boolean(extraFacets[facet.key])}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ export type NestedFilterGroupProps = {
|
|||
isPinned: (key: string, value: string | boolean) => boolean;
|
||||
onFieldPinClick?: (key: string) => void;
|
||||
isFieldPinned?: (key: string) => boolean;
|
||||
onColumnToggle?: (column: string) => void;
|
||||
displayedColumns?: string[];
|
||||
onLoadMore: (key: string) => void;
|
||||
loadMoreLoading: Record<string, boolean>;
|
||||
hasLoadedMore: Record<string, boolean>;
|
||||
|
|
@ -51,6 +53,8 @@ export const NestedFilterGroup = ({
|
|||
isPinned,
|
||||
onFieldPinClick,
|
||||
isFieldPinned,
|
||||
onColumnToggle,
|
||||
displayedColumns,
|
||||
onLoadMore,
|
||||
loadMoreLoading,
|
||||
hasLoadedMore,
|
||||
|
|
@ -153,6 +157,12 @@ export const NestedFilterGroup = ({
|
|||
isPinned={value => isPinned(child.key, value)}
|
||||
onFieldPinClick={() => onFieldPinClick?.(child.key)}
|
||||
isFieldPinned={isFieldPinned?.(child.key)}
|
||||
onColumnToggle={
|
||||
onColumnToggle
|
||||
? () => onColumnToggle(child.key)
|
||||
: undefined
|
||||
}
|
||||
isColumnDisplayed={displayedColumns?.includes(child.key)}
|
||||
onLoadMore={() => onLoadMore(child.key)}
|
||||
loadMoreLoading={loadMoreLoading[child.key] || false}
|
||||
hasLoadedMore={hasLoadedMore[child.key] || false}
|
||||
|
|
|
|||
Loading…
Reference in a new issue