@grafana/ui
Version:
Grafana Components Library
241 lines (238 loc) • 9.57 kB
JavaScript
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import { css } from '@emotion/css';
import { WKT } from 'ol/format';
import { Geometry } from 'ol/geom';
import { useMemo, useRef, useState, useLayoutEffect, useCallback } from 'react';
import { FieldType, isDataFrame, isTimeSeriesFrame } from '@grafana/data';
import { TableCellDisplayMode } from '@grafana/schema';
import { useStyles2 } from '../../../../themes/ThemeContext.mjs';
import 'micro-memoize';
import '@emotion/react';
import 'tinycolor2';
import '../../../../utils/skeleton.mjs';
import { t } from '../../../../utils/i18n.mjs';
import { IconButton } from '../../../IconButton/IconButton.mjs';
import { TableCellInspectorMode } from '../../TableCellInspector.mjs';
import { FILTER_FOR_OPERATOR, FILTER_OUT_OPERATOR } from '../types.mjs';
import { getDisplayName, getTextAlign, getCellColors } from '../utils.mjs';
import { ActionsCell } from './ActionsCell.mjs';
import AutoCell from './AutoCell.mjs';
import { BarGaugeCell } from './BarGaugeCell.mjs';
import { DataLinksCell } from './DataLinksCell.mjs';
import { GeoCell } from './GeoCell.mjs';
import { ImageCell } from './ImageCell.mjs';
import { JSONCell } from './JSONCell.mjs';
import { SparklineCell } from './SparklineCell.mjs';
function TableCellNG(props) {
var _a, _b, _c, _d, _e;
const {
field,
frame,
value,
theme,
timeRange,
height,
rowIdx,
justifyContent,
shouldTextOverflow,
setIsInspecting,
setContextMenuProps,
getActions,
rowBg,
onCellFilterAdded,
replaceVariables
} = props;
const cellInspect = (_c = (_b = (_a = field.config) == null ? void 0 : _a.custom) == null ? void 0 : _b.inspect) != null ? _c : false;
const displayName = getDisplayName(field);
const { config: fieldConfig } = field;
const defaultCellOptions = { type: TableCellDisplayMode.Auto };
const cellOptions = (_e = (_d = fieldConfig.custom) == null ? void 0 : _d.cellOptions) != null ? _e : defaultCellOptions;
const { type: cellType } = cellOptions;
const showFilters = field.config.filterable && onCellFilterAdded;
const isRightAligned = getTextAlign(field) === "flex-end";
const displayValue = field.display(value);
let colors = { bgColor: "", textColor: "", bgHoverColor: "" };
if (rowBg) {
colors = rowBg(rowIdx);
} else {
colors = useMemo(() => getCellColors(theme, cellOptions, displayValue), [theme, cellOptions, displayValue]);
}
const styles = useStyles2(getStyles, isRightAligned, colors);
const divWidthRef = useRef(null);
const [divWidth, setDivWidth] = useState(0);
const [isHovered, setIsHovered] = useState(false);
const actions = getActions ? getActions(frame, field, rowIdx, replaceVariables) : [];
useLayoutEffect(() => {
if (divWidthRef.current && divWidthRef.current.clientWidth !== 0) {
setDivWidth(divWidthRef.current.clientWidth);
}
}, [divWidthRef.current]);
const commonProps = {
value,
field,
rowIdx,
justifyContent
};
let cell = null;
switch (cellType) {
case TableCellDisplayMode.Sparkline:
cell = /* @__PURE__ */ jsx(SparklineCell, { ...commonProps, theme, timeRange, width: divWidth });
break;
case TableCellDisplayMode.Gauge:
case TableCellDisplayMode.BasicGauge:
case TableCellDisplayMode.GradientGauge:
case TableCellDisplayMode.LcdGauge:
cell = /* @__PURE__ */ jsx(BarGaugeCell, { ...commonProps, theme, timeRange, height, width: divWidth });
break;
case TableCellDisplayMode.Image:
cell = /* @__PURE__ */ jsx(ImageCell, { ...commonProps, cellOptions, height });
break;
case TableCellDisplayMode.JSONView:
cell = /* @__PURE__ */ jsx(JSONCell, { ...commonProps });
break;
case TableCellDisplayMode.DataLinks:
cell = /* @__PURE__ */ jsx(DataLinksCell, { field, rowIdx });
break;
case TableCellDisplayMode.Actions:
cell = /* @__PURE__ */ jsx(ActionsCell, { actions });
break;
case TableCellDisplayMode.Custom:
const CustomCellComponent = cellOptions.cellComponent;
cell = /* @__PURE__ */ jsx(CustomCellComponent, { field, value, rowIndex: rowIdx, frame });
break;
case TableCellDisplayMode.Auto:
default:
if (field.type === FieldType.geo) {
cell = /* @__PURE__ */ jsx(GeoCell, { ...commonProps, height });
} else if (field.type === FieldType.frame) {
const firstValue = field.values[0];
if (isDataFrame(firstValue) && isTimeSeriesFrame(firstValue)) {
cell = /* @__PURE__ */ jsx(SparklineCell, { ...commonProps, theme, timeRange, width: divWidth });
} else {
cell = /* @__PURE__ */ jsx(JSONCell, { ...commonProps });
}
} else if (field.type === FieldType.other) {
cell = /* @__PURE__ */ jsx(JSONCell, { ...commonProps });
} else {
cell = /* @__PURE__ */ jsx(AutoCell, { ...commonProps, cellOptions });
}
break;
}
const handleMouseEnter = () => {
setIsHovered(true);
if (shouldTextOverflow()) {
const div = divWidthRef.current;
const tableCellDiv = div == null ? void 0 : div.parentElement;
tableCellDiv == null ? void 0 : tableCellDiv.style.setProperty("z-index", String(theme.zIndex.tooltip));
tableCellDiv == null ? void 0 : tableCellDiv.style.setProperty("white-space", "pre-line");
tableCellDiv == null ? void 0 : tableCellDiv.style.setProperty("min-height", `100%`);
tableCellDiv == null ? void 0 : tableCellDiv.style.setProperty("height", `fit-content`);
tableCellDiv == null ? void 0 : tableCellDiv.style.setProperty("background", colors.bgHoverColor || "none");
tableCellDiv == null ? void 0 : tableCellDiv.style.setProperty("min-width", "min-content");
}
};
const handleMouseLeave = () => {
setIsHovered(false);
if (shouldTextOverflow()) {
const div = divWidthRef.current;
const tableCellDiv = div == null ? void 0 : div.parentElement;
tableCellDiv == null ? void 0 : tableCellDiv.style.removeProperty("z-index");
tableCellDiv == null ? void 0 : tableCellDiv.style.removeProperty("white-space");
tableCellDiv == null ? void 0 : tableCellDiv.style.removeProperty("min-height");
tableCellDiv == null ? void 0 : tableCellDiv.style.removeProperty("height");
tableCellDiv == null ? void 0 : tableCellDiv.style.removeProperty("background");
tableCellDiv == null ? void 0 : tableCellDiv.style.removeProperty("min-width");
}
};
const onFilterFor = useCallback(() => {
if (onCellFilterAdded) {
onCellFilterAdded({
key: displayName,
operator: FILTER_FOR_OPERATOR,
value: String(value != null ? value : "")
});
}
}, [displayName, onCellFilterAdded, value]);
const onFilterOut = useCallback(() => {
if (onCellFilterAdded) {
onCellFilterAdded({
key: displayName,
operator: FILTER_OUT_OPERATOR,
value: String(value != null ? value : "")
});
}
}, [displayName, onCellFilterAdded, value]);
return /* @__PURE__ */ jsxs("div", { ref: divWidthRef, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, className: styles.cell, children: [
cell,
isHovered && (cellInspect || showFilters) && /* @__PURE__ */ jsxs("div", { className: styles.cellActions, children: [
cellInspect && /* @__PURE__ */ jsx(
IconButton,
{
name: "eye",
tooltip: t("grafana-ui.table.cell-inspect-tooltip", "Inspect value"),
onClick: () => {
let inspectValue = value;
let mode = TableCellInspectorMode.text;
if (field.type === FieldType.geo && value instanceof Geometry) {
inspectValue = new WKT().writeGeometry(value, {
featureProjection: "EPSG:3857",
dataProjection: "EPSG:4326"
});
mode = TableCellInspectorMode.code;
} else if (cellType === TableCellDisplayMode.JSONView) {
mode = TableCellInspectorMode.code;
}
setContextMenuProps({
value: String(inspectValue != null ? inspectValue : ""),
mode
});
setIsInspecting(true);
}
}
),
showFilters && /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(
IconButton,
{
name: "search-plus",
onClick: onFilterFor,
tooltip: t("grafana-ui.table.cell-filter-on", "Filter for value")
}
),
/* @__PURE__ */ jsx(
IconButton,
{
name: "search-minus",
onClick: onFilterOut,
tooltip: t("grafana-ui.table.cell-filter-out", "Filter out value")
}
)
] })
] })
] });
}
const getStyles = (theme, isRightAligned, color) => ({
cell: css({
height: "100%",
alignContent: "center",
paddingInline: "8px",
// TODO: follow-up on this: change styles on hover on table row level
background: color.bgColor || "none",
color: color.textColor,
"&:hover": { background: color.bgHoverColor }
}),
cellActions: css({
display: "flex",
position: "absolute",
top: "1px",
left: isRightAligned ? 0 : void 0,
right: isRightAligned ? void 0 : 0,
margin: "auto",
height: "100%",
background: theme.colors.background.secondary,
color: theme.colors.text.primary,
padding: "4px 0px 4px 4px"
})
});
export { TableCellNG };
//# sourceMappingURL=TableCellNG.mjs.map