diff --git a/.betterer.results b/.betterer.results
index fc658ccf0c8..40e87849b9b 100644
--- a/.betterer.results
+++ b/.betterer.results
@@ -830,7 +830,8 @@ exports[`better eslint`] = {
],
"packages/grafana-ui/src/components/Table/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
- [0, 0, 0, "Unexpected any. Specify a different type.", "1"]
+ [0, 0, 0, "Unexpected any. Specify a different type.", "1"],
+ [0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"packages/grafana-ui/src/components/Table/utils.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
diff --git a/packages/grafana-ui/src/components/Table/CellActions.tsx b/packages/grafana-ui/src/components/Table/CellActions.tsx
index 222c441d5e2..8c70d56a481 100644
--- a/packages/grafana-ui/src/components/Table/CellActions.tsx
+++ b/packages/grafana-ui/src/components/Table/CellActions.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useState } from 'react';
+import { useCallback } from 'react';
import * as React from 'react';
import { IconSize } from '../../types/icon';
@@ -6,7 +6,7 @@ import { IconButton } from '../IconButton/IconButton';
import { Stack } from '../Layout/Stack/Stack';
import { TooltipPlacement } from '../Tooltip';
-import { TableCellInspector, TableCellInspectorMode } from './TableCellInspector';
+import { TableCellInspectorMode } from './TableCellInspector';
import { FILTER_FOR_OPERATOR, FILTER_OUT_OPERATOR, TableCellProps } from './types';
import { getTextAlign } from './utils';
@@ -20,9 +20,14 @@ interface CommonButtonProps {
tooltipPlacement: TooltipPlacement;
}
-export function CellActions({ field, cell, previewMode, showFilters, onCellFilterAdded }: CellActionProps) {
- const [isInspecting, setIsInspecting] = useState(false);
-
+export function CellActions({
+ field,
+ cell,
+ previewMode,
+ showFilters,
+ onCellFilterAdded,
+ setInspectCell,
+}: CellActionProps) {
const isRightAligned = getTextAlign(field) === 'flex-end';
const inspectEnabled = Boolean(field.config.custom?.inspect);
const commonButtonProps: CommonButtonProps = {
@@ -48,37 +53,27 @@ export function CellActions({ field, cell, previewMode, showFilters, onCellFilte
);
return (
- <>
-
-
- {inspectEnabled && (
- {
- setIsInspecting(true);
- }}
- {...commonButtonProps}
- />
- )}
- {showFilters && (
-
- )}
- {showFilters && (
-
- )}
-
-
-
- {isInspecting && (
- {
- setIsInspecting(false);
- }}
- />
- )}
- >
+
+
+ {inspectEnabled && (
+ {
+ if (setInspectCell) {
+ setInspectCell({ value: cell.value, mode: previewMode });
+ }
+ }}
+ {...commonButtonProps}
+ />
+ )}
+ {showFilters && (
+
+ )}
+ {showFilters && (
+
+ )}
+
+
);
}
diff --git a/packages/grafana-ui/src/components/Table/DefaultCell.tsx b/packages/grafana-ui/src/components/Table/DefaultCell.tsx
index d37f37d5abc..652aae07f0c 100644
--- a/packages/grafana-ui/src/components/Table/DefaultCell.tsx
+++ b/packages/grafana-ui/src/components/Table/DefaultCell.tsx
@@ -1,5 +1,5 @@
import { cx } from '@emotion/css';
-import { ReactElement, useState } from 'react';
+import { ReactElement } from 'react';
import * as React from 'react';
import { DisplayValue, formattedValueToString } from '@grafana/data';
@@ -28,18 +28,10 @@ export const DefaultCell = (props: TableCellProps) => {
const hasLinks = Boolean(getCellLinks(field, row)?.length);
const hasActions = Boolean(actions?.length);
const clearButtonStyle = useStyles2(clearLinkButtonStyles);
- const [hover, setHover] = useState(false);
let value: string | ReactElement;
const OG_TWEET_LENGTH = 140; // 🙏
- const onMouseLeave = () => {
- setHover(false);
- };
- const onMouseEnter = () => {
- setHover(true);
- };
-
if (cellOptions.type === TableCellDisplayMode.Custom) {
const CustomCellComponent: React.ComponentType = cellOptions.cellComponent;
value = ;
@@ -88,13 +80,7 @@ export const DefaultCell = (props: TableCellProps) => {
const { key, ...rest } = cellProps;
return (
-
+
{hasLinks || hasActions ? (
getCellLinks(field, row) || []} actions={actions}>
{(api) => {
@@ -118,9 +104,7 @@ export const DefaultCell = (props: TableCellProps) => {
{value}
)}
- {hover && showActions && (
-
- )}
+ {showActions && }
);
};
diff --git a/packages/grafana-ui/src/components/Table/RowsList.tsx b/packages/grafana-ui/src/components/Table/RowsList.tsx
index 646b4781fbe..b15745d3b82 100644
--- a/packages/grafana-ui/src/components/Table/RowsList.tsx
+++ b/packages/grafana-ui/src/components/Table/RowsList.tsx
@@ -24,7 +24,13 @@ import { usePanelContext } from '../PanelChrome';
import { ExpandedRow, getExpandedRowHeight } from './ExpandedRow';
import { TableCell } from './TableCell';
import { TableStyles } from './styles';
-import { CellColors, GetActionsFunction, TableFieldOptions, TableFilterActionCallback } from './types';
+import {
+ CellColors,
+ GetActionsFunction,
+ TableFieldOptions,
+ TableFilterActionCallback,
+ TableInspectCellCallback,
+} from './types';
import {
calculateAroundPointThreshold,
getCellColors,
@@ -57,6 +63,7 @@ interface RowsListProps {
textWrapField?: Field;
getActions?: GetActionsFunction;
replaceVariables?: InterpolateFunction;
+ setInspectCell?: TableInspectCellCallback;
}
export const RowsList = (props: RowsListProps) => {
@@ -85,6 +92,7 @@ export const RowsList = (props: RowsListProps) => {
textWrapField,
getActions,
replaceVariables,
+ setInspectCell,
} = props;
const [rowHighlightIndex, setRowHighlightIndex] = useState
(initialRowIndex);
@@ -346,6 +354,7 @@ export const RowsList = (props: RowsListProps) => {
height={Number(style.height)}
getActions={getActions}
replaceVariables={replaceVariables}
+ setInspectCell={setInspectCell}
/>
))}
@@ -374,6 +383,7 @@ export const RowsList = (props: RowsListProps) => {
timeRange,
getActions,
replaceVariables,
+ setInspectCell,
]
);
diff --git a/packages/grafana-ui/src/components/Table/Table.tsx b/packages/grafana-ui/src/components/Table/Table.tsx
index 54d61990463..2d8a040dc65 100644
--- a/packages/grafana-ui/src/components/Table/Table.tsx
+++ b/packages/grafana-ui/src/components/Table/Table.tsx
@@ -22,10 +22,11 @@ import { Pagination } from '../Pagination/Pagination';
import { FooterRow } from './FooterRow';
import { HeaderRow } from './HeaderRow';
import { RowsList } from './RowsList';
+import { TableCellInspector } from './TableCellInspector';
import { useFixScrollbarContainer, useResetVariableListSizeCache } from './hooks';
import { getInitialState, useTableStateReducer } from './reducer';
import { useTableStyles } from './styles';
-import { FooterItem, GrafanaTableState, Props } from './types';
+import { FooterItem, GrafanaTableState, InspectCell, Props } from './types';
import {
getColumns,
sortCaseInsensitive,
@@ -72,6 +73,7 @@ export const Table = memo((props: Props) => {
const headerHeight = noHeader ? 0 : tableStyles.rowHeight;
const [footerItems, setFooterItems] = useState(footerValues);
const noValuesDisplayText = fieldConfig?.defaults?.noValue ?? NO_DATA_TEXT;
+ const [inspectCell, setInspectCell] = useState(null);
const footerHeight = useMemo(() => {
const EXTENDED_ROW_HEIGHT = FOOTER_ROW_HEIGHT;
@@ -324,66 +326,82 @@ export const Table = memo((props: Props) => {
}
return (
-
-
-
- {!noHeader && (
-
- )}
- {itemCount > 0 ? (
-
-
+
+
+
+ {!noHeader && (
+
+ )}
+ {itemCount > 0 ? (
+
+
+
+ ) : (
+
+ {noValuesDisplayText}
+
+ )}
+ {footerItems && (
+
-
- ) : (
-
- {noValuesDisplayText}
-
- )}
- {footerItems && (
-
- )}
-
-
- {paginationEl}
-
+ )}
+
+
+ {paginationEl}
+
+
+ {inspectCell !== null && (
+ {
+ setInspectCell(null);
+ }}
+ />
+ )}
+ >
);
});
diff --git a/packages/grafana-ui/src/components/Table/TableCell.tsx b/packages/grafana-ui/src/components/Table/TableCell.tsx
index 8fa154d519e..1ca230db4d4 100644
--- a/packages/grafana-ui/src/components/Table/TableCell.tsx
+++ b/packages/grafana-ui/src/components/Table/TableCell.tsx
@@ -3,7 +3,7 @@ import { Cell } from 'react-table';
import { TimeRange, DataFrame, InterpolateFunction } from '@grafana/data';
import { TableStyles } from './styles';
-import { GetActionsFunction, GrafanaTableColumn, TableFilterActionCallback } from './types';
+import { GetActionsFunction, GrafanaTableColumn, TableFilterActionCallback, TableInspectCellCallback } from './types';
export interface Props {
cell: Cell;
@@ -20,6 +20,7 @@ export interface Props {
height?: number;
getActions?: GetActionsFunction;
replaceVariables?: InterpolateFunction;
+ setInspectCell?: TableInspectCellCallback;
}
export const TableCell = ({
@@ -35,6 +36,7 @@ export const TableCell = ({
height,
getActions,
replaceVariables,
+ setInspectCell,
}: Props) => {
const cellProps = cell.getCellProps();
const field = (cell.column as unknown as GrafanaTableColumn).field;
@@ -78,6 +80,7 @@ export const TableCell = ({
textWrapped,
height,
actions,
+ setInspectCell,
})}
>
);
diff --git a/packages/grafana-ui/src/components/Table/types.ts b/packages/grafana-ui/src/components/Table/types.ts
index 94d0c1183a2..ce1a0809f9d 100644
--- a/packages/grafana-ui/src/components/Table/types.ts
+++ b/packages/grafana-ui/src/components/Table/types.ts
@@ -14,6 +14,7 @@ import {
} from '@grafana/data';
import * as schema from '@grafana/schema';
+import { TableCellInspectorMode } from './TableCellInspector';
import { TableStyles } from './styles';
export {
@@ -33,6 +34,8 @@ export interface TableRow {
[x: string]: any;
}
+export type InspectCell = { value: any; mode: TableCellInspectorMode };
+
export const FILTER_FOR_OPERATOR = '=';
export const FILTER_OUT_OPERATOR = '!=';
export type AdHocFilterOperator = typeof FILTER_FOR_OPERATOR | typeof FILTER_OUT_OPERATOR;
@@ -40,6 +43,7 @@ export type AdHocFilterItem = { key: string; value: string; operator: AdHocFilte
export type TableFilterActionCallback = (item: AdHocFilterItem) => void;
export type TableColumnResizeActionCallback = (fieldDisplayName: string, width: number) => void;
export type TableSortByActionCallback = (state: TableSortByFieldState[]) => void;
+export type TableInspectCellCallback = (state: InspectCell) => void;
export interface TableSortByFieldState {
displayName: string;
@@ -54,6 +58,7 @@ export interface TableCellProps extends CellProps {
innerWidth: number;
frame: DataFrame;
actions?: ActionModel[];
+ setInspectCell?: TableInspectCellCallback;
}
export type CellComponent = FC;