Table: Fix regression with Filter popup expression selection (#111777)
This commit is contained in:
@@ -861,21 +861,6 @@
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/grafana-ui/src/components/Table/TableNG/Filter/Filter.tsx": {
|
||||
"@typescript-eslint/no-explicit-any": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/grafana-ui/src/components/Table/TableNG/Filter/FilterPopup.tsx": {
|
||||
"@typescript-eslint/no-explicit-any": {
|
||||
"count": 3
|
||||
}
|
||||
},
|
||||
"packages/grafana-ui/src/components/Table/TableNG/Filter/utils.ts": {
|
||||
"@typescript-eslint/no-explicit-any": {
|
||||
"count": 1
|
||||
}
|
||||
},
|
||||
"packages/grafana-ui/src/components/Table/TableNG/TableNG.test.tsx": {
|
||||
"@typescript-eslint/no-explicit-any": {
|
||||
"count": 2
|
||||
|
||||
@@ -20,13 +20,14 @@ export interface Props<T> extends HTMLAttributes<HTMLButtonElement> {
|
||||
narrow?: boolean;
|
||||
variant?: ToolbarButtonVariant;
|
||||
tooltip?: string;
|
||||
root?: HTMLElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use Combobox or Dropdown instead
|
||||
*/
|
||||
const ButtonSelectComponent = <T,>(props: Props<T>) => {
|
||||
const { className, options, value, onChange, narrow, variant, ...restProps } = props;
|
||||
const { className, options, value, onChange, narrow, variant, root, ...restProps } = props;
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const renderMenu = () => (
|
||||
@@ -50,7 +51,7 @@ const ButtonSelectComponent = <T,>(props: Props<T>) => {
|
||||
);
|
||||
|
||||
return (
|
||||
<Dropdown overlay={renderMenu} placement="bottom-end">
|
||||
<Dropdown root={root} overlay={renderMenu} placement="bottom-end">
|
||||
<ToolbarButton className={className} isOpen={isOpen} narrow={narrow} variant={variant} {...restProps}>
|
||||
{value?.label || (value?.value != null ? String(value?.value) : null)}
|
||||
</ToolbarButton>
|
||||
|
||||
@@ -25,12 +25,13 @@ export interface Props {
|
||||
overlay: React.ReactElement | (() => React.ReactElement);
|
||||
placement?: TooltipPlacement;
|
||||
children: React.ReactElement;
|
||||
root?: HTMLElement;
|
||||
/** Amount in pixels to nudge the dropdown vertically and horizontally, respectively. */
|
||||
offset?: [number, number];
|
||||
onVisibleChange?: (state: boolean) => void;
|
||||
}
|
||||
|
||||
export const Dropdown = React.memo(({ children, overlay, placement, offset, onVisibleChange }: Props) => {
|
||||
export const Dropdown = React.memo(({ children, overlay, placement, offset, root, onVisibleChange }: Props) => {
|
||||
const [show, setShow] = useState(false);
|
||||
const transitionRef = useRef(null);
|
||||
const floatingUIPlacement = getPlacement(placement);
|
||||
@@ -84,7 +85,7 @@ export const Dropdown = React.memo(({ children, overlay, placement, offset, onVi
|
||||
...getReferenceProps(),
|
||||
})}
|
||||
{show && (
|
||||
<Portal>
|
||||
<Portal root={root}>
|
||||
<FloatingFocusManager context={context}>
|
||||
{/*
|
||||
this is handling bubbled events from the inner overlay
|
||||
|
||||
@@ -14,9 +14,9 @@ import { FilterPopup } from './FilterPopup';
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
rows: any[];
|
||||
rows: TableRow[];
|
||||
filter: FilterType;
|
||||
setFilter: (value: FilterType) => void;
|
||||
setFilter: React.Dispatch<React.SetStateAction<FilterType>>;
|
||||
field?: Field;
|
||||
crossFilterOrder: string[];
|
||||
crossFilterRows: { [key: string]: TableRow[] };
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import { Field, GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
@@ -12,7 +12,7 @@ import { ButtonSelect } from '../../../Dropdown/ButtonSelect';
|
||||
import { FilterInput } from '../../../FilterInput/FilterInput';
|
||||
import { Label } from '../../../Forms/Label';
|
||||
import { Stack } from '../../../Layout/Stack/Stack';
|
||||
import { FilterType } from '../types';
|
||||
import { FilterType, TableRow } from '../types';
|
||||
import { getDisplayName } from '../utils';
|
||||
|
||||
import { FilterList } from './FilterList';
|
||||
@@ -36,9 +36,9 @@ const OPERATORS = Object.values(operatorSelectableValues);
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
rows: any[];
|
||||
filterValue: any;
|
||||
setFilter: (value: any) => void;
|
||||
rows: TableRow[];
|
||||
filterValue?: Array<SelectableValue<unknown>>;
|
||||
setFilter: React.Dispatch<React.SetStateAction<FilterType>>;
|
||||
onClose: () => void;
|
||||
field?: Field;
|
||||
searchFilter: string;
|
||||
@@ -65,6 +65,7 @@ export const FilterPopup = ({
|
||||
const filteredOptions = useMemo(() => getFilteredOptions(options, filterValue), [options, filterValue]);
|
||||
const [values, setValues] = useState<SelectableValue[]>(filteredOptions);
|
||||
const [matchCase, setMatchCase] = useState(false);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const onCancel = useCallback((event?: React.MouseEvent) => onClose(), [onClose]);
|
||||
|
||||
@@ -114,6 +115,7 @@ export const FilterPopup = ({
|
||||
className={styles.filterContainer}
|
||||
onClick={stopPropagation}
|
||||
data-testid={selectors.components.Panels.Visualization.TableNG.Filters.Container}
|
||||
ref={containerRef}
|
||||
>
|
||||
<Stack direction="column">
|
||||
<Stack alignItems="center">
|
||||
@@ -124,6 +126,7 @@ export const FilterPopup = ({
|
||||
onChange={setOperator}
|
||||
value={operator}
|
||||
tooltip={operator.description}
|
||||
root={containerRef.current ?? undefined}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Field, formattedValueToString, SelectableValue } from '@grafana/data';
|
||||
|
||||
import { TableRow } from '../types';
|
||||
import { getDisplayName } from '../utils';
|
||||
|
||||
export function calculateUniqueFieldValues(rows: any[], field?: Field) {
|
||||
export function calculateUniqueFieldValues(rows: TableRow[], field?: Field) {
|
||||
if (!field || rows.length === 0) {
|
||||
return {};
|
||||
}
|
||||
@@ -12,8 +13,7 @@ export function calculateUniqueFieldValues(rows: any[], field?: Field) {
|
||||
for (let index = 0; index < rows.length; index++) {
|
||||
const row = rows[index];
|
||||
const fieldValue = row[getDisplayName(field)];
|
||||
const displayValue = field.display ? field.display(fieldValue) : fieldValue;
|
||||
const value = field.display ? formattedValueToString(displayValue) : displayValue;
|
||||
const value = field.display ? formattedValueToString(field.display(fieldValue)) : String(fieldValue);
|
||||
|
||||
set[value || '(Blanks)'] = value;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user