@grafana/ui
Version:
Grafana Components Library
966 lines (959 loc) • 38.1 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var jsxRuntime = require('react/jsx-runtime');
require('@grafana/react-data-grid/lib/styles.css');
var clsx = require('clsx');
var memoize = require('micro-memoize');
var React = require('react');
var data = require('@grafana/data');
var i18n = require('@grafana/i18n');
var reactDataGrid = require('@grafana/react-data-grid');
var schema = require('@grafana/schema');
var ThemeContext = require('../../../themes/ThemeContext.cjs');
var colors = require('../../../utils/colors.cjs');
var Pagination = require('../../Pagination/Pagination.cjs');
require('../../PanelChrome/index.cjs');
var DataLinksActionsTooltip = require('../DataLinksActionsTooltip.cjs');
var TableCellInspector = require('../TableCellInspector.cjs');
var index = require('../geo/index.cjs');
require('../types.cjs');
var renderers = require('./Cells/renderers.cjs');
var EmptyTablePlaceholder = require('./components/EmptyTablePlaceholder.cjs');
var HeaderCell = require('./components/HeaderCell.cjs');
var RowExpander = require('./components/RowExpander.cjs');
var SummaryCell = require('./components/SummaryCell.cjs');
var TableCellActions = require('./components/TableCellActions.cjs');
var TableCellTooltip = require('./components/TableCellTooltip.cjs');
var constants = require('./constants.cjs');
var hooks = require('./hooks.cjs');
var styles = require('./styles.cjs');
var utils = require('./utils.cjs');
var PanelContext = require('../../PanelChrome/PanelContext.cjs');
var utils$1 = require('../geo/utils.cjs');
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
var memoize__default = /*#__PURE__*/_interopDefaultCompat(memoize);
"use strict";
const EXPANDED_COLUMN_KEY = "expanded";
function TableNG(props) {
var _a, _b;
const {
cellHeight,
data: data$1,
disableKeyboardEvents,
disableSanitizeHtml,
enablePagination = false,
enableSharedCrosshair = false,
enableVirtualization,
frozenColumns: _frozenColumns = 0,
getActions = () => [],
height,
maxRowHeight: _maxRowHeight,
noHeader,
noValue,
onCellFilterAdded,
onColumnResize,
onSortByChange,
protoParserEnabled,
showTypeIcons,
structureRev,
timeRange,
transparent,
width,
initialRowIndex,
sortBy,
sortByBehavior = "initial"
} = props;
const uniqueId = React.useId();
const theme = ThemeContext.useTheme2();
const panelContext = PanelContext.usePanelContext();
const userCanExecuteActions = React.useMemo(() => {
var _a2, _b2;
return (_b2 = (_a2 = panelContext.canExecuteActions) == null ? void 0 : _a2.call(panelContext)) != null ? _b2 : false;
}, [panelContext]);
const getCellActions = React.useCallback(
(field, rowIdx) => {
if (!userCanExecuteActions) {
return [];
}
return getActions(data$1, field, rowIdx);
},
[getActions, data$1, userCanExecuteActions]
);
const visibleFields = React.useMemo(() => utils.getVisibleFields(data$1.fields), [data$1.fields]);
const hasHeader = !noHeader;
const hasFooter = React.useMemo(
() => visibleFields.some((field) => {
var _a2, _b2, _c;
return Boolean((_c = (_b2 = (_a2 = field.config.custom) == null ? void 0 : _a2.footer) == null ? void 0 : _b2.reducers) == null ? void 0 : _c.length);
}),
[visibleFields]
);
const footerHeight = React.useMemo(
() => hasFooter ? utils.calculateFooterHeight(visibleFields) : 0,
[hasFooter, visibleFields]
);
const resizeHandler = hooks.useColumnResize(onColumnResize);
const nestedResizeHandler = hooks.useColumnResize(onColumnResize, "nested");
const hasNestedFrames = React.useMemo(() => utils.getIsNestedTable(data$1.fields), [data$1]);
const tableHasGeoCell = React.useMemo(() => utils$1.hasGeoCell(data$1), [data$1]);
const nestedFramesFieldName = React.useMemo(() => {
if (!hasNestedFrames) {
return;
}
const firstNestedField = data$1.fields.find((f) => f.type === data.FieldType.nestedFrames);
if (!firstNestedField) {
return;
}
return utils.getDisplayName(firstNestedField);
}, [data$1, hasNestedFrames]);
const frameToRecords = React.useMemo(
() => protoParserEnabled ? utils.compileFrameToRecordsV2(data$1, nestedFramesFieldName) : utils.compileFrameToRecordsV1(data$1, nestedFramesFieldName),
[data$1, nestedFramesFieldName, protoParserEnabled]
);
const rows = React.useMemo(() => frameToRecords(data$1), [frameToRecords, data$1]);
const nestedData = React.useMemo(
() => {
var _a2;
return hasNestedFrames ? (_a2 = data$1.fields.find((f) => utils.getDisplayName(f) === nestedFramesFieldName)) == null ? void 0 : _a2.values.map((v) => v[0]) : void 0;
},
[data$1, nestedFramesFieldName, hasNestedFrames]
);
const getStableRowKeyForRowIdx = React.useCallback(
(rowIdx) => utils.getStableRowKey(rowIdx, nestedData == null ? void 0 : nestedData[rowIdx]),
[nestedData]
);
const firstRowNestedData = React.useMemo(
() => hasNestedFrames && nestedData ? nestedData[0] : void 0,
[nestedData, hasNestedFrames]
);
const nestedFields = React.useMemo(() => {
var _a2;
return (_a2 = firstRowNestedData == null ? void 0 : firstRowNestedData.fields) != null ? _a2 : [];
}, [firstRowNestedData]);
const nestedVisibleFields = React.useMemo(() => utils.getVisibleFields(nestedFields), [nestedFields]);
const nestedHasFooter = React.useMemo(
() => nestedVisibleFields.some((field) => {
var _a2, _b2, _c;
return Boolean((_c = (_b2 = (_a2 = field.config.custom) == null ? void 0 : _a2.footer) == null ? void 0 : _b2.reducers) == null ? void 0 : _c.length);
}),
[nestedVisibleFields]
);
const nestedFooterHeight = React.useMemo(
() => nestedHasFooter ? utils.calculateFooterHeight(nestedVisibleFields) : 0,
[nestedHasFooter, nestedVisibleFields]
);
const { rows: filteredRows, filter, setFilter, filterResult } = hooks.useFilteredRows(rows, data$1.fields, hasNestedFrames);
const {
rows: sortedRows,
sortColumns,
setSortColumns
} = hooks.useSortedRows(filteredRows, data$1.fields, nestedFields, { hasNestedFrames, initialSortBy: sortBy });
hooks.useManagedSort({ sortByBehavior, setSortColumns, sortBy });
const nestedRows = hooks.useNestedRows(rows, nestedData, hasNestedFrames, nestedFramesFieldName, filter, sortColumns);
const [inspectCell, setInspectCell] = React.useState(null);
const [tooltipState, setTooltipState] = React.useState();
const onCellClick = React.useCallback(
({ column, row }, ev) => {
var _a2;
const field = column.field;
if (column.key === EXPANDED_COLUMN_KEY) {
return;
}
if (ev.target instanceof HTMLElement && // this walks up the tree to find either a faux link wrapper or the cell root
// it then only proceeds if we matched the faux link wrapper
((_a2 = ev.target.closest("a[aria-haspopup], .rdg-cell")) == null ? void 0 : _a2.matches("a"))) {
const rowIdx = row.__index;
setTooltipState({
coords: {
clientX: ev.clientX,
clientY: ev.clientY
},
links: utils.getCellLinks(field, rowIdx),
actions: getCellActions(field, rowIdx)
});
ev.preventGridDefault();
}
},
[getCellActions]
);
const [expandedRows, setExpandedRows] = React.useState(() => {
var _a2, _b2;
if ((_b2 = (_a2 = data$1.meta) == null ? void 0 : _a2.custom) == null ? void 0 : _b2.expandAllRows) {
const nestedField = data$1.fields.find((f) => f.type === data.FieldType.nestedFrames);
return new Set(Array.from({ length: data$1.length }, (_, i) => {
var _a3;
return utils.getStableRowKey(i, (_a3 = nestedField == null ? void 0 : nestedField.values[i]) == null ? void 0 : _a3[0]);
}));
}
return /* @__PURE__ */ new Set();
});
const [selectedRows, setSelectedRows] = React.useState(() => /* @__PURE__ */ new Set());
const gridRef = React.useRef(null);
const scrollbarWidth = hooks.useScrollbarWidth(gridRef, height);
const availableWidth = React.useMemo(
() => (hasNestedFrames ? width - constants.COLUMN.EXPANDER_WIDTH : width) - scrollbarWidth,
[width, hasNestedFrames, scrollbarWidth]
);
const getCellColorInlineStyles = React.useMemo(() => utils.getCellColorInlineStylesFactory(theme), [theme]);
const applyToRowBgFn = React.useMemo(
() => {
var _a2;
return (_a2 = utils.getApplyToRowBgFn(data$1.fields, getCellColorInlineStyles)) != null ? _a2 : void 0;
},
[data$1.fields, getCellColorInlineStyles]
);
const getTextColorForBackground = React.useMemo(() => memoize__default.default(colors.getTextColorForBackground, { maxSize: 1e3 }), []);
const typographyCtx = React.useMemo(
() => utils.createTypographyContext(
theme.typography.fontSize,
theme.typography.fontFamily,
utils.extractPixelValue(theme.typography.body.letterSpacing) * theme.typography.fontSize
),
[theme]
);
const frozenColumns = React.useMemo(() => hasNestedFrames ? 0 : _frozenColumns, [hasNestedFrames, _frozenColumns]);
const configuredWidthCount = visibleFields.reduce(
(count, field) => {
var _a2;
return count + (((_a2 = field.config.custom) == null ? void 0 : _a2.width) != null ? 1 : 0);
},
0
);
const prevConfiguredWidthCount = React.useRef(configuredWidthCount);
const widthConfigResetKey = configuredWidthCount < prevConfiguredWidthCount.current ? Symbol() : void 0;
const resetColumnWidths = widthConfigResetKey != null ? /* @__PURE__ */ new Map() : void 0;
prevConfiguredWidthCount.current = configuredWidthCount;
const [widths, numFrozenColsFullyInView] = hooks.useColWidths(
visibleFields,
availableWidth,
frozenColumns,
widthConfigResetKey
);
const headerHeight = hooks.useHeaderHeight({
columnWidths: widths,
fields: visibleFields,
enabled: hasHeader,
sortColumns,
showTypeIcons: showTypeIcons != null ? showTypeIcons : false,
typographyCtx
});
const maxRowHeight = _maxRowHeight != null ? Math.max(constants.TABLE.LINE_HEIGHT, _maxRowHeight) : void 0;
const visibleNestedRowCounts = React.useMemo(
() => nestedRows.map((row, idx) => expandedRows.has(getStableRowKeyForRowIdx(idx)) ? row.final.length : null),
[nestedRows, expandedRows, getStableRowKeyForRowIdx]
);
const { nestedFieldWidths, nestedColWidths, handleNestedColumnWidthsChange } = hooks.useNestedColWidths({
nestedVisibleFields,
availableWidth,
structureRev
});
const hasNestedHeaders = React.useMemo(() => {
var _a2, _b2;
return ((_b2 = (_a2 = firstRowNestedData == null ? void 0 : firstRowNestedData.meta) == null ? void 0 : _a2.custom) == null ? void 0 : _b2.noHeader) !== true;
}, [firstRowNestedData]);
const nestedHeaderHeight = hooks.useHeaderHeight({
columnWidths: nestedFieldWidths,
fields: nestedVisibleFields,
enabled: hasNestedHeaders,
sortColumns,
showTypeIcons: showTypeIcons != null ? showTypeIcons : false,
typographyCtx
});
const defaultRowHeight = React.useMemo(
() => utils.getDefaultRowHeight(theme, visibleFields, cellHeight),
[theme, visibleFields, cellHeight]
);
const defaultNestedRowHeight = React.useMemo(
() => utils.getDefaultRowHeight(theme, nestedVisibleFields, cellHeight),
[theme, nestedVisibleFields, cellHeight]
);
const rowHeight = hooks.useRowHeight({
columnWidths: widths,
fields: visibleFields,
hasNestedFrames,
defaultHeight: defaultRowHeight,
defaultNestedHeight: defaultNestedRowHeight,
visibleNestedRowCounts,
typographyCtx,
maxHeight: maxRowHeight,
nestedColWidths: nestedFieldWidths,
nestedFields: nestedVisibleFields,
nestedRows,
nestedFooterHeight
});
const {
rows: paginatedRows,
page,
setPage,
numPages,
numRows,
pageRangeStart,
pageRangeEnd,
smallPagination
} = hooks.usePaginatedRows(sortedRows, {
enabled: enablePagination,
width: availableWidth,
height,
footerHeight,
headerHeight: hasHeader ? headerHeight : 0,
rowHeight,
hasNestedFrames
});
const showPagination = enablePagination && numRows > 0;
const styles$1 = ThemeContext.useStyles2(styles.getGridStyles, showPagination, transparent);
const [scrollToIndex, setScrollToIndex] = React.useState(initialRowIndex);
React.useEffect(() => {
var _a2;
if (scrollToIndex !== void 0 && sortedRows && ((_a2 = gridRef.current) == null ? void 0 : _a2.scrollToCell)) {
const rowIdx = sortedRows.findIndex((row) => row.__index === scrollToIndex);
gridRef.current.scrollToCell({
rowIdx
});
setScrollToIndex(void 0);
setSelectedRows(/* @__PURE__ */ new Set([utils.rowKeyGetter(sortedRows[rowIdx])]));
}
}, [scrollToIndex, sortedRows]);
const rowHeightFn = React.useMemo(() => {
if (typeof defaultNestedRowHeight === "string") {
return (row) => expandedRows.has(getStableRowKeyForRowIdx(row.__index)) ? constants.TABLE.MAX_CELL_HEIGHT : 0;
}
if (typeof rowHeight === "function") {
return rowHeight;
}
if (typeof rowHeight === "string") {
return () => constants.TABLE.MAX_CELL_HEIGHT;
}
return () => rowHeight;
}, [rowHeight, defaultNestedRowHeight, expandedRows, getStableRowKeyForRowIdx]);
const renderRow = React.useMemo(
() => renderRowFactory(data$1.fields, panelContext, expandedRows, enableSharedCrosshair, getStableRowKeyForRowIdx),
[data$1.fields, panelContext, expandedRows, enableSharedCrosshair, getStableRowKeyForRowIdx]
);
const commonDataGridProps = React.useMemo(
() => ({
enableVirtualization: !utils.IS_SAFARI_26 && enableVirtualization !== false && typeof rowHeight !== "string",
defaultColumnOptions: {
minWidth: 50,
resizable: true,
sortable: true
// draggable: true,
},
onSortColumnsChange: (newSortColumns) => {
setSortColumns(newSortColumns);
onSortByChange == null ? void 0 : onSortByChange(
newSortColumns.map(({ columnKey, direction }) => ({
displayName: columnKey,
desc: direction === "DESC"
}))
);
},
sortColumns,
rowHeight,
bottomSummaryRows: hasFooter ? [{}] : void 0,
summaryRowHeight: footerHeight,
headerRowClass: styles$1.headerRow,
headerRowHeight: noHeader ? 0 : headerHeight
}),
[
enableVirtualization,
hasFooter,
sortColumns,
rowHeight,
styles$1.headerRow,
noHeader,
setSortColumns,
onSortByChange,
footerHeight,
headerHeight
]
);
const buildNestedTableExpanderColumn = React.useCallback(
(nestedColumnsMatrix2, hasNestedHeaders2, nestedHeaderHeightPx, hasNestedFooter, nestedFooterHeightPx, renderers) => ({
key: EXPANDED_COLUMN_KEY,
sortable: false,
resizable: false,
name: i18n.t("grafana-ui.table.nested-table.expander-column-name", "Expand nested rows"),
field: {
name: "",
type: data.FieldType.other,
config: {},
values: []
},
cellClass(row) {
if (row.__depth !== 0) {
return styles$1.cellNested;
}
return;
},
colSpan(args) {
return args.type === "ROW" && args.row.__depth === 1 ? data$1.fields.length : 1;
},
renderCell: ({ row }) => {
var _a2, _b2;
const rowId = `${uniqueId}-nested-table-${row.__index}`;
if (row.__depth === 0) {
const rowIdx = row.__index;
const stableKey = getStableRowKeyForRowIdx(rowIdx);
return /* @__PURE__ */ jsxRuntime.jsx(
RowExpander.RowExpander,
{
rowId,
isExpanded: expandedRows.has(stableKey),
onCellExpand: () => {
setExpandedRows((er) => {
if (er.has(stableKey)) {
er.delete(stableKey);
} else {
er.add(stableKey);
}
return new Set(er);
});
}
}
);
}
const expandedRecords = (_b2 = (_a2 = nestedRows[row.__index]) == null ? void 0 : _a2.final) != null ? _b2 : [];
if (!expandedRecords.length) {
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles$1.noDataNested, children: /* @__PURE__ */ jsxRuntime.jsx(i18n.Trans, { i18nKey: "grafana-ui.table.nested-table.no-data", children: "No data" }) });
}
const nestedColumns = nestedColumnsMatrix2[row.__index].columns;
return /* @__PURE__ */ jsxRuntime.jsx("div", { id: rowId, children: /* @__PURE__ */ jsxRuntime.jsx(
reactDataGrid.DataGrid,
{
...commonDataGridProps,
className: clsx.clsx(styles$1.grid, styles$1.gridNested),
headerRowClass: clsx.clsx(styles$1.headerRow, hasNestedHeaders2 ? "" : styles$1.displayNone),
headerRowHeight: hasNestedHeaders2 ? nestedHeaderHeightPx : 0,
bottomSummaryRows: hasNestedFooter ? [{}] : void 0,
summaryRowHeight: nestedFooterHeightPx,
onColumnResize: nestedResizeHandler,
columns: nestedColumns,
rows: expandedRecords,
renderers: { ...renderers, noRowsFallback: /* @__PURE__ */ jsxRuntime.jsx(EmptyTablePlaceholder.EmptyTablePlaceholder, { noValue }) },
onCellClick,
columnWidths: nestedColWidths,
onColumnWidthsChange: handleNestedColumnWidthsChange
}
) });
},
renderHeaderCell(props2) {
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sr-only", children: props2.column.name });
},
width: constants.COLUMN.EXPANDER_WIDTH,
minWidth: constants.COLUMN.EXPANDER_WIDTH
}),
[
styles$1.cellNested,
styles$1.grid,
styles$1.gridNested,
styles$1.headerRow,
styles$1.displayNone,
styles$1.noDataNested,
data$1.fields.length,
commonDataGridProps,
expandedRows,
getStableRowKeyForRowIdx,
nestedRows,
noValue,
onCellClick,
uniqueId,
nestedColWidths,
nestedResizeHandler,
handleNestedColumnWidthsChange
]
);
const fromFields = React.useCallback(
(f, widths2, frame, rawRows, visibleRows) => {
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
const result = {
columns: [],
cellRootRenderers: {}
};
const fieldFooters = [];
let isFieldUniformFooter = true;
let firstFooterReducers;
for (const field of f) {
const footer = (_b2 = (_a2 = field.config) == null ? void 0 : _a2.custom) == null ? void 0 : _b2.footer;
const reducers = footer == null ? void 0 : footer.reducers;
fieldFooters.push(footer);
if (reducers === void 0 || reducers.length === 0) {
continue;
}
if (firstFooterReducers === void 0) {
firstFooterReducers = reducers;
continue;
}
if (reducers.length !== firstFooterReducers.length || reducers.some((r, idx) => (firstFooterReducers == null ? void 0 : firstFooterReducers[idx]) !== r)) {
isFieldUniformFooter = false;
break;
}
}
const parentIndex = (_c = visibleRows[0]) == null ? void 0 : _c.__parentIndex;
const { crossFilterRows, crossFilterTailRows } = parentIndex == null ? filterResult : nestedRows[parentIndex].filterResult;
let lastRowIdx = -1;
let rowCellStyle = {
color: void 0,
background: void 0
};
for (let i = 0; i < f.length; i++) {
let field = f[i];
const cellOptions = utils.getCellOptions(field);
const cellType = cellOptions.type;
if (cellType === schema.TableCellDisplayMode.Pill && ((_e = (_d = field.config.mappings) == null ? void 0 : _d.length) != null ? _e : 0 > 0)) {
field = {
...field,
config: {
...field.config,
color: {
...field.config.color,
mode: schema.FieldColorModeId.Fixed,
fixedColor: (_g = (_f = field.config.color) == null ? void 0 : _f.fixedColor) != null ? _g : data.FALLBACK_COLOR
}
}
};
field.display = data.getDisplayProcessor({ field, theme });
}
if (cellType === schema.TableCellDisplayMode.JSONView || field.type === data.FieldType.other) {
field.display = utils.displayJsonValue(field);
}
const textAlign = utils.getAlignment(field);
const justifyContent = utils.getJustifyContent(textAlign);
const displayName = utils.getDisplayName(field);
const headerCellClass = styles.getHeaderCellStyles(theme, justifyContent);
const CellType = renderers.getCellRenderer(field, cellOptions);
const cellInspect = utils.isCellInspectEnabled(field);
const showFilters = Boolean(field.config.filterable && onCellFilterAdded != null);
const showActions = cellInspect || showFilters;
const width2 = widths2[i];
const cellActionClassName = showActions ? clsx.clsx("table-cell-actions", styles.getCellActionStyles(theme, textAlign)) : void 0;
const shouldOverflow = !utils.IS_SAFARI_26 && typeof rowHeight !== "string" && (utils.shouldTextOverflow(field) || Boolean(maxRowHeight));
const textWrap = typeof rowHeight === "string" || utils.shouldTextWrap(field);
const canBeColorized = utils.canFieldBeColorized(cellType, applyToRowBgFn);
const cellStyleOptions = {
textAlign,
textWrap,
shouldOverflow,
maxHeight: maxRowHeight
};
const defaultCellStyles = styles.getDefaultCellStyles(theme, cellStyleOptions);
const cellSpecificStyles = renderers.getCellSpecificStyles(cellType, field, theme, cellStyleOptions);
const linkStyles = styles.getLinkStyles(theme, canBeColorized);
const cellParentStyles = clsx.clsx(defaultCellStyles, linkStyles);
const maxHeightClassName = maxRowHeight ? styles.getMaxHeightCellStyles(theme, cellStyleOptions) : void 0;
const styleFieldValue = (_h = field.config.custom) == null ? void 0 : _h.styleField;
const styleField = styleFieldValue ? frame.fields.find(utils.predicateByName(styleFieldValue)) : void 0;
const styleFieldName = styleField ? utils.getDisplayName(styleField) : void 0;
const hasValidStyleField = Boolean(styleFieldName);
const renderCellRoot2 = (key, props2) => {
const rowIdx = props2.row.__index;
if (rowIdx !== lastRowIdx) {
lastRowIdx = rowIdx;
rowCellStyle.color = void 0;
rowCellStyle.background = void 0;
if (applyToRowBgFn != null) {
rowCellStyle = { ...rowCellStyle, ...applyToRowBgFn(rowIdx) };
}
}
let style = { ...rowCellStyle };
if (canBeColorized) {
const value = props2.row[props2.column.key];
const displayValue = field.display(value);
const cellColorStyles = getCellColorInlineStyles(cellOptions, displayValue, applyToRowBgFn != null);
Object.assign(style, cellColorStyles);
}
if (hasValidStyleField) {
style = { ...style, ...utils.parseStyleJson(props2.row[styleFieldName]) };
}
return /* @__PURE__ */ jsxRuntime.jsx(
reactDataGrid.Cell,
{
...props2,
className: clsx.clsx(
props2.className,
cellParentStyles,
cellSpecificStyles != null && maxRowHeight == null ? cellSpecificStyles : ""
),
style
},
key
);
};
result.cellRootRenderers[displayName] = renderCellRoot2;
const renderBasicCellContent = (props2) => {
const rowIdx = props2.row.__index;
const value = props2.row[props2.column.key];
const height2 = rowHeightFn(props2.row);
let result2 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsx(
CellType,
{
cellOptions,
frame,
field,
height: height2,
rowIdx,
theme,
value,
width: width2,
timeRange,
cellInspect,
showFilters,
getActions: getCellActions,
disableSanitizeHtml,
getTextColorForBackground
}
),
showActions && /* @__PURE__ */ jsxRuntime.jsx(
TableCellActions.TableCellActions,
{
field,
value,
displayName,
cellInspect,
showFilters,
className: cellActionClassName,
setInspectCell,
onCellFilterAdded
}
)
] });
if (maxRowHeight != null) {
result2 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx.clsx(maxHeightClassName, cellSpecificStyles), children: result2 });
}
return result2;
};
let renderCellContent = renderBasicCellContent;
const tooltipFieldName = (_j = (_i = field.config.custom) == null ? void 0 : _i.tooltip) == null ? void 0 : _j.field;
if (tooltipFieldName) {
const tooltipField = frame.fields.find(utils.predicateByName(tooltipFieldName));
if (tooltipField) {
const tooltipDisplayName = utils.getDisplayName(tooltipField);
const tooltipCellOptions = utils.getCellOptions(tooltipField);
const tooltipFieldRenderer = renderers.getCellRenderer(tooltipField, tooltipCellOptions);
const tooltipCellStyleOptions = {
textAlign: utils.getAlignment(tooltipField),
textWrap: utils.shouldTextWrap(tooltipField),
shouldOverflow: false,
maxHeight: maxRowHeight
};
const tooltipCanBeColorized = utils.canFieldBeColorized(tooltipCellOptions.type, applyToRowBgFn);
const tooltipDefaultStyles = styles.getDefaultCellStyles(theme, tooltipCellStyleOptions);
const tooltipSpecificStyles = renderers.getCellSpecificStyles(
tooltipCellOptions.type,
tooltipField,
theme,
tooltipCellStyleOptions
);
const tooltipLinkStyles = styles.getLinkStyles(theme, tooltipCanBeColorized);
const tooltipClasses = styles.getTooltipStyles(theme, textAlign);
const placement = (_m = (_l = (_k = field.config.custom) == null ? void 0 : _k.tooltip) == null ? void 0 : _l.placement) != null ? _m : schema.TableCellTooltipPlacement.Auto;
const tooltipWidth = placement === schema.TableCellTooltipPlacement.Left || placement === schema.TableCellTooltipPlacement.Right ? (_n = tooltipField.config.custom) == null ? void 0 : _n.width : width2;
const tooltipProps = {
cellOptions: tooltipCellOptions,
classes: tooltipClasses,
className: clsx.clsx(
tooltipClasses.tooltipContent,
tooltipDefaultStyles,
tooltipSpecificStyles,
tooltipLinkStyles
),
data: frame,
disableSanitizeHtml,
field: tooltipField,
getActions: getCellActions,
getTextColorForBackground,
gridRef,
placement,
renderer: tooltipFieldRenderer,
tooltipField,
theme,
width: tooltipWidth
};
renderCellContent = (props2) => {
const tooltipHeight = rowHeightFn(props2.row);
let tooltipStyle = { ...rowCellStyle };
if (tooltipCanBeColorized) {
const tooltipDisplayValue = tooltipField.display(props2.row[tooltipDisplayName]);
const tooltipCellColorStyles = getCellColorInlineStyles(
tooltipCellOptions,
tooltipDisplayValue,
applyToRowBgFn != null
);
Object.assign(tooltipStyle, tooltipCellColorStyles);
}
return /* @__PURE__ */ jsxRuntime.jsx(
TableCellTooltip.TableCellTooltip,
{
...tooltipProps,
height: tooltipHeight,
rowIdx: props2.row.__index,
style: tooltipStyle,
children: renderBasicCellContent(props2)
}
);
};
}
}
result.columns.push({
field,
key: displayName,
name: displayName,
width: width2,
headerCellClass,
frozen: Math.min(frozenColumns, numFrozenColsFullyInView) > i,
renderCell: renderCellContent,
renderHeaderCell: ({ column, sortDirection }) => /* @__PURE__ */ jsxRuntime.jsx(
HeaderCell.HeaderCell,
{
column,
rows: rawRows,
field,
filter,
setFilter,
disableKeyboardEvents,
direction: sortDirection,
showTypeIcons,
parentIndex,
crossFilterRows,
crossFilterTailRows,
selectFirstCell: () => {
var _a3;
(_a3 = gridRef.current) == null ? void 0 : _a3.selectCell({ rowIdx: 0, idx: 0 });
}
}
),
renderSummaryCell: () => /* @__PURE__ */ jsxRuntime.jsx(
SummaryCell.SummaryCell,
{
rows: visibleRows,
footers: fieldFooters,
field,
colIdx: i,
textAlign: utils.getSummaryCellTextAlign(textAlign, cellType),
rowLabel: isFieldUniformFooter && i === 0,
hideLabel: isFieldUniformFooter && i !== 0
}
)
});
}
return result;
},
[
applyToRowBgFn,
disableKeyboardEvents,
disableSanitizeHtml,
filter,
filterResult,
frozenColumns,
getCellActions,
getCellColorInlineStyles,
getTextColorForBackground,
maxRowHeight,
nestedRows,
numFrozenColsFullyInView,
onCellFilterAdded,
rowHeight,
rowHeightFn,
setFilter,
showTypeIcons,
theme,
timeRange
]
);
const nestedColumnsMatrix = React.useMemo(() => {
const result = [];
if (!hasNestedFrames) {
return result;
}
for (const row of rows) {
if (row.__depth > 0) {
const rowNestedFrame = nestedData[row.__index];
result.push(
fromFields(
utils.getVisibleFields(rowNestedFrame.fields),
nestedFieldWidths,
rowNestedFrame,
nestedRows[row.__index].raw,
nestedRows[row.__index].final
)
);
}
}
return result;
}, [rows, hasNestedFrames, nestedData, nestedRows, nestedFieldWidths, fromFields]);
const { columns, cellRootRenderers } = React.useMemo(() => {
const result = fromFields(visibleFields, widths, data$1, rows, sortedRows);
if (!firstRowNestedData) {
return result;
}
const renderRow2 = renderRowFactory(
firstRowNestedData.fields,
panelContext,
expandedRows,
enableSharedCrosshair,
getStableRowKeyForRowIdx
);
const expanderCellRenderer = (key, props2) => /* @__PURE__ */ jsxRuntime.jsx(reactDataGrid.Cell, { ...props2 }, key);
result.cellRootRenderers[EXPANDED_COLUMN_KEY] = expanderCellRenderer;
result.columns.unshift(
buildNestedTableExpanderColumn(
nestedColumnsMatrix,
hasNestedHeaders,
nestedHeaderHeight,
nestedHasFooter,
nestedFooterHeight,
{
renderRow: renderRow2,
renderCell: (key, props2) => nestedColumnsMatrix[props2.row.__parentIndex].cellRootRenderers[props2.column.key](key, props2)
}
)
);
return result;
}, [
buildNestedTableExpanderColumn,
data$1,
enableSharedCrosshair,
expandedRows,
firstRowNestedData,
fromFields,
getStableRowKeyForRowIdx,
hasNestedHeaders,
nestedColumnsMatrix,
nestedFooterHeight,
nestedHasFooter,
nestedHeaderHeight,
panelContext,
rows,
sortedRows,
visibleFields,
widths
]);
const structureRevColumns = React.useMemo(() => columns, [columns, structureRev]);
const renderCellRoot = React.useCallback(
(key, props2) => cellRootRenderers[props2.column.key](key, props2),
[cellRootRenderers]
);
const itemsRangeStart = pageRangeStart;
const displayedEnd = pageRangeEnd;
let rendered = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsx(
reactDataGrid.DataGrid,
{
...commonDataGridProps,
role: hasNestedFrames ? "treegrid" : "grid",
ref: gridRef,
className: styles$1.grid,
columns: structureRevColumns,
rows: paginatedRows,
rowKeyGetter: utils.rowKeyGetter,
isRowSelectionDisabled: () => initialRowIndex !== void 0,
selectedRows,
onSelectedRowsChange: setSelectedRows,
headerRowClass: clsx.clsx(styles$1.headerRow, noHeader ? styles$1.displayNone : ""),
headerRowHeight: headerHeight,
columnWidths: resetColumnWidths,
onColumnWidthsChange: resetColumnWidths != null ? () => {
} : void 0,
onColumnResize: resizeHandler,
onCellClick,
onCellKeyDown: ({ column, row }, event) => {
var _a2;
if (column.key === columns[0].key && row.__index === 0 && event.shiftKey && event.key === "Tab") {
event.preventGridDefault();
(_a2 = gridRef.current) == null ? void 0 : _a2.selectCell({ rowIdx: -1, idx: columns.length - 1 });
return;
}
if (disableKeyboardEvents || hasNestedFrames && event.isDefaultPrevented()) {
event.preventGridDefault();
}
},
renderers: {
renderRow,
renderCell: renderCellRoot,
noRowsFallback: /* @__PURE__ */ jsxRuntime.jsx(EmptyTablePlaceholder.EmptyTablePlaceholder, { noValue })
}
}
),
enablePagination && numRows > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles$1.paginationContainer, children: [
/* @__PURE__ */ jsxRuntime.jsx(
Pagination.Pagination,
{
className: "table-ng-pagination",
currentPage: page + 1,
numberOfPages: numPages,
showSmallVersion: smallPagination,
onNavigate: (toPage) => {
setPage(toPage - 1);
}
}
),
!smallPagination && /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles$1.paginationSummary, children: /* @__PURE__ */ jsxRuntime.jsxs(i18n.Trans, { i18nKey: "grafana-ui.table.pagination-summary", children: [
{ itemsRangeStart },
" - ",
{ displayedEnd },
" of ",
{ numRows },
" rows"
] }) })
] }),
tooltipState && /* @__PURE__ */ jsxRuntime.jsx(
DataLinksActionsTooltip.DataLinksActionsTooltip,
{
links: (_a = tooltipState.links) != null ? _a : [],
actions: tooltipState.actions,
coords: tooltipState.coords,
onTooltipClose: () => setTooltipState(void 0)
}
),
inspectCell && /* @__PURE__ */ jsxRuntime.jsx(
TableCellInspector.TableCellInspector,
{
mode: (_b = inspectCell.mode) != null ? _b : TableCellInspector.TableCellInspectorMode.text,
value: inspectCell.value,
onDismiss: () => setInspectCell(null)
}
)
] });
if (utils.IS_SAFARI_26) {
rendered = /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles$1.safariWrapper, children: rendered });
}
if (!tableHasGeoCell) {
return rendered;
}
return /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: rendered, children: /* @__PURE__ */ jsxRuntime.jsx(index.LazyOpenLayersProvider, { children: rendered }) });
}
const renderRowFactory = (fields, panelContext, expandedRows, enableSharedCrosshair, getStableKey) => (
// eslint-disable-next-line react/display-name
(key, props) => {
const { row } = props;
const rowIdx = row.__index;
const isExpanded = expandedRows.has(getStableKey(rowIdx));
if (row.__depth === 1) {
if (!isExpanded) {
return null;
}
return /* @__PURE__ */ jsxRuntime.jsx(reactDataGrid.Row, { "aria-level": row.__index + 1, "aria-expanded": isExpanded, ...props }, key);
}
const handlers = {};
if (enableSharedCrosshair) {
const timeField = fields.find((f) => f.type === data.FieldType.time);
if (timeField) {
handlers.onMouseEnter = () => {
panelContext.eventBus.publish(
new data.DataHoverEvent({
point: {
time: timeField == null ? void 0 : timeField.values[rowIdx]
}
})
);
};
handlers.onMouseLeave = () => {
panelContext.eventBus.publish(new data.DataHoverClearEvent());
};
}
}
return /* @__PURE__ */ jsxRuntime.jsx(reactDataGrid.Row, { ...props, ...handlers }, key);
}
);
exports.TableNG = TableNG;
//# sourceMappingURL=TableNG.cjs.map