@@ -28,6 +28,9 @@ import { ColumnDef } from '@tanstack/react-table';
2828import { useVirtualizer } from '@tanstack/react-virtual' ;
2929
3030import { CsvExportButton } from './components/CsvExportButton' ;
31+ import DBRowTableFieldWithPopover , {
32+ type CellFilterHandler ,
33+ } from './components/DBTable/DBRowTableFieldWithPopover' ;
3134import TableHeader from './components/DBTable/TableHeader' ;
3235import { useCsvExport } from './hooks/useCsvExport' ;
3336import type { RowAction } from './hooks/useOnClickLinkBuilder' ;
@@ -61,6 +64,7 @@ export const Table = ({
6164 variant = 'default' ,
6265 alternateRowBackground = false ,
6366 className,
67+ onCellFilter,
6468} : {
6569 data : any [ ] ;
6670 columns : {
@@ -78,6 +82,9 @@ export const Table = ({
7882 // Ordered conditional color rules evaluated against each cell's value
7983 // (last match wins). Resolves to `color` when no rule matches.
8084 colorRules ?: ColorCondition [ ] ;
85+ // Expression (or PromQL label) the column's values filter on. Cells of a
86+ // column with a key offer filter / exclude actions via `onCellFilter`.
87+ filterKey ?: string ;
8188 } [ ] ;
8289 groupColumnName ?: string ;
8390 // Returns the row click destination + a hover-hint description. When
@@ -105,6 +112,7 @@ export const Table = ({
105112 // Extra classes for the scroll container, e.g. `effect-pulse` while the
106113 // tile is refreshing.
107114 className ?: string ;
115+ onCellFilter ?: CellFilterHandler ;
108116} ) => {
109117 const brandName = useBrandDisplayName ( ) ;
110118 const MIN_COLUMN_WIDTH_PX = 100 ;
@@ -163,6 +171,7 @@ export const Table = ({
163171 sortingFn,
164172 color,
165173 colorRules,
174+ filterKey,
166175 } ,
167176 i ,
168177 ) =>
@@ -189,6 +198,27 @@ export const Table = ({
189198 formattedValue = formatNumber ( value , numberFormat ) ;
190199 }
191200
201+ // Map / Array values render as JSON, which their `toString()`
202+ // in a filter condition wouldn't match.
203+ const content : React . ReactNode =
204+ filterKey &&
205+ onCellFilter &&
206+ value != null &&
207+ typeof value !== 'object' ? (
208+ < DBRowTableFieldWithPopover
209+ cellValue = { value }
210+ columnName = { filterKey }
211+ onPropertyAddClick = { onCellFilter }
212+ wrapLinesEnabled = { wrapLinesEnabled }
213+ tableContainerRef = { tableContainerRef . current }
214+ inline
215+ >
216+ { formattedValue }
217+ </ DBRowTableFieldWithPopover >
218+ ) : (
219+ formattedValue
220+ ) ;
221+
192222 // Resolve this cell's color from the column config: ordered
193223 // rules first (last match wins), then the column's static
194224 // color, else no override. ClickHouse serializes numeric
@@ -257,7 +287,7 @@ export const Table = ({
257287 data-testid = "dashboard-table-row-action"
258288 data-shape = "external-link"
259289 >
260- { formattedValue }
290+ { content }
261291 </ a >
262292 ) ;
263293 }
@@ -273,7 +303,7 @@ export const Table = ({
273303 data-testid = "dashboard-table-row-action"
274304 data-shape = "link"
275305 >
276- { formattedValue }
306+ { content }
277307 </ Link >
278308 ) ;
279309 }
@@ -295,7 +325,7 @@ export const Table = ({
295325 data-testid = "dashboard-table-row-action"
296326 data-shape = "button"
297327 >
298- { formattedValue }
328+ { content }
299329 </ button >
300330 ) ;
301331 }
@@ -312,15 +342,15 @@ export const Table = ({
312342 data-testid = "dashboard-table-row-action"
313343 data-shape = "link"
314344 >
315- { formattedValue }
345+ { content }
316346 </ Link >
317347 ) ;
318348 }
319349 }
320350
321351 return (
322352 < div className = { className } style = { colorStyle } >
323- { formattedValue }
353+ { content }
324354 </ div >
325355 ) ;
326356 } ,
0 commit comments