UNPKG

@grafana/ui

Version:
241 lines (238 loc) • 9.57 kB
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