UNPKG

@grafana/ui

Version:
958 lines (955 loc) • 37.3 kB
import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; import '@grafana/react-data-grid/lib/styles.css'; import { clsx } from 'clsx'; import memoize from 'micro-memoize'; import { useId, useMemo, useCallback, useState, useRef, useEffect, Suspense } from 'react'; import { FieldType, FALLBACK_COLOR, getDisplayProcessor, DataHoverEvent, DataHoverClearEvent } from '@grafana/data'; import { Trans, t } from '@grafana/i18n'; import { DataGrid, Cell, Row } from '@grafana/react-data-grid'; import { TableCellDisplayMode, FieldColorModeId, TableCellTooltipPlacement } from '@grafana/schema'; import { useTheme2, useStyles2 } from '../../../themes/ThemeContext.mjs'; import { getTextColorForBackground } from '../../../utils/colors.mjs'; import { Pagination } from '../../Pagination/Pagination.mjs'; import '../../PanelChrome/index.mjs'; import { DataLinksActionsTooltip } from '../DataLinksActionsTooltip.mjs'; import { TableCellInspector, TableCellInspectorMode } from '../TableCellInspector.mjs'; import { LazyOpenLayersProvider } from '../geo/index.mjs'; import '../types.mjs'; import { getCellRenderer, getCellSpecificStyles } from './Cells/renderers.mjs'; import { EmptyTablePlaceholder } from './components/EmptyTablePlaceholder.mjs'; import { HeaderCell } from './components/HeaderCell.mjs'; import { RowExpander } from './components/RowExpander.mjs'; import { SummaryCell } from './components/SummaryCell.mjs'; import { TableCellActions } from './components/TableCellActions.mjs'; import { TableCellTooltip } from './components/TableCellTooltip.mjs'; import { COLUMN, TABLE } from './constants.mjs'; import { useColumnResize, useFilteredRows, useSortedRows, useManagedSort, useNestedRows, useScrollbarWidth, useColWidths, useHeaderHeight, useNestedColWidths, useRowHeight, usePaginatedRows } from './hooks.mjs'; import { getGridStyles, getHeaderCellStyles, getCellActionStyles, getDefaultCellStyles, getLinkStyles, getMaxHeightCellStyles, getTooltipStyles } from './styles.mjs'; import { getVisibleFields, calculateFooterHeight, getIsNestedTable, getDisplayName, compileFrameToRecordsV2, compileFrameToRecordsV1, getStableRowKey, getCellLinks, getCellColorInlineStylesFactory, getApplyToRowBgFn, createTypographyContext, extractPixelValue, getDefaultRowHeight, rowKeyGetter, IS_SAFARI_26, getCellOptions, displayJsonValue, getAlignment, getJustifyContent, isCellInspectEnabled, shouldTextOverflow, shouldTextWrap, canFieldBeColorized, predicateByName, parseStyleJson, getSummaryCellTextAlign } from './utils.mjs'; import { usePanelContext } from '../../PanelChrome/PanelContext.mjs'; import { hasGeoCell } from '../geo/utils.mjs'; "use strict"; const EXPANDED_COLUMN_KEY = "expanded"; function TableNG(props) { var _a, _b; const { cellHeight, data, 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 = useId(); const theme = useTheme2(); const panelContext = usePanelContext(); const userCanExecuteActions = useMemo(() => { var _a2, _b2; return (_b2 = (_a2 = panelContext.canExecuteActions) == null ? void 0 : _a2.call(panelContext)) != null ? _b2 : false; }, [panelContext]); const getCellActions = useCallback( (field, rowIdx) => { if (!userCanExecuteActions) { return []; } return getActions(data, field, rowIdx); }, [getActions, data, userCanExecuteActions] ); const visibleFields = useMemo(() => getVisibleFields(data.fields), [data.fields]); const hasHeader = !noHeader; const hasFooter = 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 = useMemo( () => hasFooter ? calculateFooterHeight(visibleFields) : 0, [hasFooter, visibleFields] ); const resizeHandler = useColumnResize(onColumnResize); const nestedResizeHandler = useColumnResize(onColumnResize, "nested"); const hasNestedFrames = useMemo(() => getIsNestedTable(data.fields), [data]); const tableHasGeoCell = useMemo(() => hasGeoCell(data), [data]); const nestedFramesFieldName = useMemo(() => { if (!hasNestedFrames) { return; } const firstNestedField = data.fields.find((f) => f.type === FieldType.nestedFrames); if (!firstNestedField) { return; } return getDisplayName(firstNestedField); }, [data, hasNestedFrames]); const frameToRecords = useMemo( () => protoParserEnabled ? compileFrameToRecordsV2(data, nestedFramesFieldName) : compileFrameToRecordsV1(data, nestedFramesFieldName), [data, nestedFramesFieldName, protoParserEnabled] ); const rows = useMemo(() => frameToRecords(data), [frameToRecords, data]); const nestedData = useMemo( () => { var _a2; return hasNestedFrames ? (_a2 = data.fields.find((f) => getDisplayName(f) === nestedFramesFieldName)) == null ? void 0 : _a2.values.map((v) => v[0]) : void 0; }, [data, nestedFramesFieldName, hasNestedFrames] ); const getStableRowKeyForRowIdx = useCallback( (rowIdx) => getStableRowKey(rowIdx, nestedData == null ? void 0 : nestedData[rowIdx]), [nestedData] ); const firstRowNestedData = useMemo( () => hasNestedFrames && nestedData ? nestedData[0] : void 0, [nestedData, hasNestedFrames] ); const nestedFields = useMemo(() => { var _a2; return (_a2 = firstRowNestedData == null ? void 0 : firstRowNestedData.fields) != null ? _a2 : []; }, [firstRowNestedData]); const nestedVisibleFields = useMemo(() => getVisibleFields(nestedFields), [nestedFields]); const nestedHasFooter = 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 = useMemo( () => nestedHasFooter ? calculateFooterHeight(nestedVisibleFields) : 0, [nestedHasFooter, nestedVisibleFields] ); const { rows: filteredRows, filter, setFilter, filterResult } = useFilteredRows(rows, data.fields, hasNestedFrames); const { rows: sortedRows, sortColumns, setSortColumns } = useSortedRows(filteredRows, data.fields, nestedFields, { hasNestedFrames, initialSortBy: sortBy }); useManagedSort({ sortByBehavior, setSortColumns, sortBy }); const nestedRows = useNestedRows(rows, nestedData, hasNestedFrames, nestedFramesFieldName, filter, sortColumns); const [inspectCell, setInspectCell] = useState(null); const [tooltipState, setTooltipState] = useState(); const onCellClick = 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: getCellLinks(field, rowIdx), actions: getCellActions(field, rowIdx) }); ev.preventGridDefault(); } }, [getCellActions] ); const [expandedRows, setExpandedRows] = useState(() => { var _a2, _b2; if ((_b2 = (_a2 = data.meta) == null ? void 0 : _a2.custom) == null ? void 0 : _b2.expandAllRows) { const nestedField = data.fields.find((f) => f.type === FieldType.nestedFrames); return new Set(Array.from({ length: data.length }, (_, i) => { var _a3; return getStableRowKey(i, (_a3 = nestedField == null ? void 0 : nestedField.values[i]) == null ? void 0 : _a3[0]); })); } return /* @__PURE__ */ new Set(); }); const [selectedRows, setSelectedRows] = useState(() => /* @__PURE__ */ new Set()); const gridRef = useRef(null); const scrollbarWidth = useScrollbarWidth(gridRef, height); const availableWidth = useMemo( () => (hasNestedFrames ? width - COLUMN.EXPANDER_WIDTH : width) - scrollbarWidth, [width, hasNestedFrames, scrollbarWidth] ); const getCellColorInlineStyles = useMemo(() => getCellColorInlineStylesFactory(theme), [theme]); const applyToRowBgFn = useMemo( () => { var _a2; return (_a2 = getApplyToRowBgFn(data.fields, getCellColorInlineStyles)) != null ? _a2 : void 0; }, [data.fields, getCellColorInlineStyles] ); const getTextColorForBackground$1 = useMemo(() => memoize(getTextColorForBackground, { maxSize: 1e3 }), []); const typographyCtx = useMemo( () => createTypographyContext( theme.typography.fontSize, theme.typography.fontFamily, extractPixelValue(theme.typography.body.letterSpacing) * theme.typography.fontSize ), [theme] ); const frozenColumns = 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 = 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] = useColWidths( visibleFields, availableWidth, frozenColumns, widthConfigResetKey ); const headerHeight = useHeaderHeight({ columnWidths: widths, fields: visibleFields, enabled: hasHeader, sortColumns, showTypeIcons: showTypeIcons != null ? showTypeIcons : false, typographyCtx }); const maxRowHeight = _maxRowHeight != null ? Math.max(TABLE.LINE_HEIGHT, _maxRowHeight) : void 0; const visibleNestedRowCounts = useMemo( () => nestedRows.map((row, idx) => expandedRows.has(getStableRowKeyForRowIdx(idx)) ? row.final.length : null), [nestedRows, expandedRows, getStableRowKeyForRowIdx] ); const { nestedFieldWidths, nestedColWidths, handleNestedColumnWidthsChange } = useNestedColWidths({ nestedVisibleFields, availableWidth, structureRev }); const hasNestedHeaders = 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 = useHeaderHeight({ columnWidths: nestedFieldWidths, fields: nestedVisibleFields, enabled: hasNestedHeaders, sortColumns, showTypeIcons: showTypeIcons != null ? showTypeIcons : false, typographyCtx }); const defaultRowHeight = useMemo( () => getDefaultRowHeight(theme, visibleFields, cellHeight), [theme, visibleFields, cellHeight] ); const defaultNestedRowHeight = useMemo( () => getDefaultRowHeight(theme, nestedVisibleFields, cellHeight), [theme, nestedVisibleFields, cellHeight] ); const rowHeight = 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 } = usePaginatedRows(sortedRows, { enabled: enablePagination, width: availableWidth, height, footerHeight, headerHeight: hasHeader ? headerHeight : 0, rowHeight, hasNestedFrames }); const showPagination = enablePagination && numRows > 0; const styles = useStyles2(getGridStyles, showPagination, transparent); const [scrollToIndex, setScrollToIndex] = useState(initialRowIndex); 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([rowKeyGetter(sortedRows[rowIdx])])); } }, [scrollToIndex, sortedRows]); const rowHeightFn = useMemo(() => { if (typeof defaultNestedRowHeight === "string") { return (row) => expandedRows.has(getStableRowKeyForRowIdx(row.__index)) ? TABLE.MAX_CELL_HEIGHT : 0; } if (typeof rowHeight === "function") { return rowHeight; } if (typeof rowHeight === "string") { return () => TABLE.MAX_CELL_HEIGHT; } return () => rowHeight; }, [rowHeight, defaultNestedRowHeight, expandedRows, getStableRowKeyForRowIdx]); const renderRow = useMemo( () => renderRowFactory(data.fields, panelContext, expandedRows, enableSharedCrosshair, getStableRowKeyForRowIdx), [data.fields, panelContext, expandedRows, enableSharedCrosshair, getStableRowKeyForRowIdx] ); const commonDataGridProps = useMemo( () => ({ enableVirtualization: !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.headerRow, headerRowHeight: noHeader ? 0 : headerHeight }), [ enableVirtualization, hasFooter, sortColumns, rowHeight, styles.headerRow, noHeader, setSortColumns, onSortByChange, footerHeight, headerHeight ] ); const buildNestedTableExpanderColumn = useCallback( (nestedColumnsMatrix2, hasNestedHeaders2, nestedHeaderHeightPx, hasNestedFooter, nestedFooterHeightPx, renderers) => ({ key: EXPANDED_COLUMN_KEY, sortable: false, resizable: false, name: t("grafana-ui.table.nested-table.expander-column-name", "Expand nested rows"), field: { name: "", type: FieldType.other, config: {}, values: [] }, cellClass(row) { if (row.__depth !== 0) { return styles.cellNested; } return; }, colSpan(args) { return args.type === "ROW" && args.row.__depth === 1 ? data.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__ */ jsx( 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__ */ jsx("div", { className: styles.noDataNested, children: /* @__PURE__ */ jsx(Trans, { i18nKey: "grafana-ui.table.nested-table.no-data", children: "No data" }) }); } const nestedColumns = nestedColumnsMatrix2[row.__index].columns; return /* @__PURE__ */ jsx("div", { id: rowId, children: /* @__PURE__ */ jsx( DataGrid, { ...commonDataGridProps, className: clsx(styles.grid, styles.gridNested), headerRowClass: clsx(styles.headerRow, hasNestedHeaders2 ? "" : styles.displayNone), headerRowHeight: hasNestedHeaders2 ? nestedHeaderHeightPx : 0, bottomSummaryRows: hasNestedFooter ? [{}] : void 0, summaryRowHeight: nestedFooterHeightPx, onColumnResize: nestedResizeHandler, columns: nestedColumns, rows: expandedRecords, renderers: { ...renderers, noRowsFallback: /* @__PURE__ */ jsx(EmptyTablePlaceholder, { noValue }) }, onCellClick, columnWidths: nestedColWidths, onColumnWidthsChange: handleNestedColumnWidthsChange } ) }); }, renderHeaderCell(props2) { return /* @__PURE__ */ jsx("div", { className: "sr-only", children: props2.column.name }); }, width: COLUMN.EXPANDER_WIDTH, minWidth: COLUMN.EXPANDER_WIDTH }), [ styles.cellNested, styles.grid, styles.gridNested, styles.headerRow, styles.displayNone, styles.noDataNested, data.fields.length, commonDataGridProps, expandedRows, getStableRowKeyForRowIdx, nestedRows, noValue, onCellClick, uniqueId, nestedColWidths, nestedResizeHandler, handleNestedColumnWidthsChange ] ); const fromFields = 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 = getCellOptions(field); const cellType = cellOptions.type; if (cellType === 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: FieldColorModeId.Fixed, fixedColor: (_g = (_f = field.config.color) == null ? void 0 : _f.fixedColor) != null ? _g : FALLBACK_COLOR } } }; field.display = getDisplayProcessor({ field, theme }); } if (cellType === TableCellDisplayMode.JSONView || field.type === FieldType.other) { field.display = displayJsonValue(field); } const textAlign = getAlignment(field); const justifyContent = getJustifyContent(textAlign); const displayName = getDisplayName(field); const headerCellClass = getHeaderCellStyles(theme, justifyContent); const CellType = getCellRenderer(field, cellOptions); const cellInspect = isCellInspectEnabled(field); const showFilters = Boolean(field.config.filterable && onCellFilterAdded != null); const showActions = cellInspect || showFilters; const width2 = widths2[i]; const cellActionClassName = showActions ? clsx("table-cell-actions", getCellActionStyles(theme, textAlign)) : void 0; const shouldOverflow = !IS_SAFARI_26 && typeof rowHeight !== "string" && (shouldTextOverflow(field) || Boolean(maxRowHeight)); const textWrap = typeof rowHeight === "string" || shouldTextWrap(field); const canBeColorized = canFieldBeColorized(cellType, applyToRowBgFn); const cellStyleOptions = { textAlign, textWrap, shouldOverflow, maxHeight: maxRowHeight }; const defaultCellStyles = getDefaultCellStyles(theme, cellStyleOptions); const cellSpecificStyles = getCellSpecificStyles(cellType, field, theme, cellStyleOptions); const linkStyles = getLinkStyles(theme, canBeColorized); const cellParentStyles = clsx(defaultCellStyles, linkStyles); const maxHeightClassName = maxRowHeight ? getMaxHeightCellStyles(theme, cellStyleOptions) : void 0; const styleFieldValue = (_h = field.config.custom) == null ? void 0 : _h.styleField; const styleField = styleFieldValue ? frame.fields.find(predicateByName(styleFieldValue)) : void 0; const styleFieldName = styleField ? 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, ...parseStyleJson(props2.row[styleFieldName]) }; } return /* @__PURE__ */ jsx( Cell, { ...props2, className: 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__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx( CellType, { cellOptions, frame, field, height: height2, rowIdx, theme, value, width: width2, timeRange, cellInspect, showFilters, getActions: getCellActions, disableSanitizeHtml, getTextColorForBackground: getTextColorForBackground$1 } ), showActions && /* @__PURE__ */ jsx( TableCellActions, { field, value, displayName, cellInspect, showFilters, className: cellActionClassName, setInspectCell, onCellFilterAdded } ) ] }); if (maxRowHeight != null) { result2 = /* @__PURE__ */ jsx("div", { className: 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(predicateByName(tooltipFieldName)); if (tooltipField) { const tooltipDisplayName = getDisplayName(tooltipField); const tooltipCellOptions = getCellOptions(tooltipField); const tooltipFieldRenderer = getCellRenderer(tooltipField, tooltipCellOptions); const tooltipCellStyleOptions = { textAlign: getAlignment(tooltipField), textWrap: shouldTextWrap(tooltipField), shouldOverflow: false, maxHeight: maxRowHeight }; const tooltipCanBeColorized = canFieldBeColorized(tooltipCellOptions.type, applyToRowBgFn); const tooltipDefaultStyles = getDefaultCellStyles(theme, tooltipCellStyleOptions); const tooltipSpecificStyles = getCellSpecificStyles( tooltipCellOptions.type, tooltipField, theme, tooltipCellStyleOptions ); const tooltipLinkStyles = getLinkStyles(theme, tooltipCanBeColorized); const tooltipClasses = getTooltipStyles(theme, textAlign); const placement = (_m = (_l = (_k = field.config.custom) == null ? void 0 : _k.tooltip) == null ? void 0 : _l.placement) != null ? _m : TableCellTooltipPlacement.Auto; const tooltipWidth = placement === TableCellTooltipPlacement.Left || placement === TableCellTooltipPlacement.Right ? (_n = tooltipField.config.custom) == null ? void 0 : _n.width : width2; const tooltipProps = { cellOptions: tooltipCellOptions, classes: tooltipClasses, className: clsx( tooltipClasses.tooltipContent, tooltipDefaultStyles, tooltipSpecificStyles, tooltipLinkStyles ), data: frame, disableSanitizeHtml, field: tooltipField, getActions: getCellActions, getTextColorForBackground: getTextColorForBackground$1, 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__ */ jsx( 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__ */ jsx( 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__ */ jsx( SummaryCell, { rows: visibleRows, footers: fieldFooters, field, colIdx: i, textAlign: getSummaryCellTextAlign(textAlign, cellType), rowLabel: isFieldUniformFooter && i === 0, hideLabel: isFieldUniformFooter && i !== 0 } ) }); } return result; }, [ applyToRowBgFn, disableKeyboardEvents, disableSanitizeHtml, filter, filterResult, frozenColumns, getCellActions, getCellColorInlineStyles, getTextColorForBackground$1, maxRowHeight, nestedRows, numFrozenColsFullyInView, onCellFilterAdded, rowHeight, rowHeightFn, setFilter, showTypeIcons, theme, timeRange ] ); const nestedColumnsMatrix = useMemo(() => { const result = []; if (!hasNestedFrames) { return result; } for (const row of rows) { if (row.__depth > 0) { const rowNestedFrame = nestedData[row.__index]; result.push( fromFields( getVisibleFields(rowNestedFrame.fields), nestedFieldWidths, rowNestedFrame, nestedRows[row.__index].raw, nestedRows[row.__index].final ) ); } } return result; }, [rows, hasNestedFrames, nestedData, nestedRows, nestedFieldWidths, fromFields]); const { columns, cellRootRenderers } = useMemo(() => { const result = fromFields(visibleFields, widths, data, rows, sortedRows); if (!firstRowNestedData) { return result; } const renderRow2 = renderRowFactory( firstRowNestedData.fields, panelContext, expandedRows, enableSharedCrosshair, getStableRowKeyForRowIdx ); const expanderCellRenderer = (key, props2) => /* @__PURE__ */ jsx(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, enableSharedCrosshair, expandedRows, firstRowNestedData, fromFields, getStableRowKeyForRowIdx, hasNestedHeaders, nestedColumnsMatrix, nestedFooterHeight, nestedHasFooter, nestedHeaderHeight, panelContext, rows, sortedRows, visibleFields, widths ]); const structureRevColumns = useMemo(() => columns, [columns, structureRev]); const renderCellRoot = useCallback( (key, props2) => cellRootRenderers[props2.column.key](key, props2), [cellRootRenderers] ); const itemsRangeStart = pageRangeStart; const displayedEnd = pageRangeEnd; let rendered = /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx( DataGrid, { ...commonDataGridProps, role: hasNestedFrames ? "treegrid" : "grid", ref: gridRef, className: styles.grid, columns: structureRevColumns, rows: paginatedRows, rowKeyGetter, isRowSelectionDisabled: () => initialRowIndex !== void 0, selectedRows, onSelectedRowsChange: setSelectedRows, headerRowClass: clsx(styles.headerRow, noHeader ? styles.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__ */ jsx(EmptyTablePlaceholder, { noValue }) } } ), enablePagination && numRows > 0 && /* @__PURE__ */ jsxs("div", { className: styles.paginationContainer, children: [ /* @__PURE__ */ jsx( Pagination, { className: "table-ng-pagination", currentPage: page + 1, numberOfPages: numPages, showSmallVersion: smallPagination, onNavigate: (toPage) => { setPage(toPage - 1); } } ), !smallPagination && /* @__PURE__ */ jsx("div", { className: styles.paginationSummary, children: /* @__PURE__ */ jsxs(Trans, { i18nKey: "grafana-ui.table.pagination-summary", children: [ { itemsRangeStart }, " - ", { displayedEnd }, " of ", { numRows }, " rows" ] }) }) ] }), tooltipState && /* @__PURE__ */ jsx( DataLinksActionsTooltip, { links: (_a = tooltipState.links) != null ? _a : [], actions: tooltipState.actions, coords: tooltipState.coords, onTooltipClose: () => setTooltipState(void 0) } ), inspectCell && /* @__PURE__ */ jsx( TableCellInspector, { mode: (_b = inspectCell.mode) != null ? _b : TableCellInspectorMode.text, value: inspectCell.value, onDismiss: () => setInspectCell(null) } ) ] }); if (IS_SAFARI_26) { rendered = /* @__PURE__ */ jsx("div", { className: styles.safariWrapper, children: rendered }); } if (!tableHasGeoCell) { return rendered; } return /* @__PURE__ */ jsx(Suspense, { fallback: rendered, children: /* @__PURE__ */ jsx(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__ */ jsx(Row, { "aria-level": row.__index + 1, "aria-expanded": isExpanded, ...props }, key); } const handlers = {}; if (enableSharedCrosshair) { const timeField = fields.find((f) => f.type === FieldType.time); if (timeField) { handlers.onMouseEnter = () => { panelContext.eventBus.publish( new DataHoverEvent({ point: { time: timeField == null ? void 0 : timeField.values[rowIdx] } }) ); }; handlers.onMouseLeave = () => { panelContext.eventBus.publish(new DataHoverClearEvent()); }; } } return /* @__PURE__ */ jsx(Row, { ...props, ...handlers }, key); } ); export { TableNG }; //# sourceMappingURL=TableNG.mjs.map