UNPKG

@grafana/ui

Version:
331 lines (326 loc) • 11.9 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var jsxRuntime = require('react/jsx-runtime'); var React = require('react'); var reactTable = require('react-table'); var data = require('@grafana/data'); var e2eSelectors = require('@grafana/e2e-selectors'); var i18n = require('@grafana/i18n'); var schema = require('@grafana/schema'); var ThemeContext = require('../../../themes/ThemeContext.cjs'); var CustomScrollbar = require('../../CustomScrollbar/CustomScrollbar.cjs'); var Pagination = require('../../Pagination/Pagination.cjs'); var TableCellInspector = require('../TableCellInspector.cjs'); var index = require('../geo/index.cjs'); var hooks = require('../hooks.cjs'); var reducer = require('../reducer.cjs'); var utils = require('../utils.cjs'); var FooterRow = require('./FooterRow.cjs'); var HeaderRow = require('./HeaderRow.cjs'); var RowsList = require('./RowsList.cjs'); var styles = require('./styles.cjs'); var utils$1 = require('../geo/utils.cjs'); "use strict"; const COLUMN_MIN_WIDTH = 150; const FOOTER_ROW_HEIGHT = 36; const NO_DATA_TEXT = "No data"; const Table = React.memo((props) => { var _a, _b, _c, _d; const { ariaLabel, data: data$1, height, onCellFilterAdded, onColumnResize, width, columnMinWidth = COLUMN_MIN_WIDTH, noHeader, resizable = true, initialSortBy, footerOptions, showTypeIcons, footerValues, enablePagination, cellHeight = schema.TableCellHeight.Sm, timeRange, enableSharedCrosshair = false, initialRowIndex = void 0, fieldConfig, getActions, replaceVariables } = props; const listRef = React.useRef(null); const tableDivRef = React.useRef(null); const variableSizeListScrollbarRef = React.useRef(null); const theme = ThemeContext.useTheme2(); const tableStyles = styles.useTableStyles(theme, cellHeight); const headerHeight = noHeader ? 0 : tableStyles.rowHeight; const [footerItems, setFooterItems] = React.useState(footerValues); const noValuesDisplayText = (_b = (_a = fieldConfig == null ? void 0 : fieldConfig.defaults) == null ? void 0 : _a.noValue) != null ? _b : NO_DATA_TEXT; const [inspectCell, setInspectCell] = React.useState(null); const footerHeight = React.useMemo(() => { const EXTENDED_ROW_HEIGHT = FOOTER_ROW_HEIGHT; let length = 0; if (!footerItems) { return 0; } for (const fv of footerItems) { if (Array.isArray(fv) && fv.length > length) { length = fv.length; } } if (length > 1) { return EXTENDED_ROW_HEIGHT * length; } return EXTENDED_ROW_HEIGHT; }, [footerItems]); const memoizedData = React.useMemo(() => { if (!data$1.fields.length) { return []; } return Array(data$1.length).fill(0); }, [data$1]); const isCountRowsSet = Boolean( (footerOptions == null ? void 0 : footerOptions.countRows) && footerOptions.reducer && footerOptions.reducer.length && footerOptions.reducer[0] === data.ReducerID.count ); const nestedDataField = data$1.fields.find((f) => f.type === data.FieldType.nestedFrames); const hasNestedData = nestedDataField !== void 0; const memoizedColumns = React.useMemo( () => utils.getColumns(data$1, width, columnMinWidth, hasNestedData, footerItems, isCountRowsSet), [data$1, width, columnMinWidth, hasNestedData, footerItems, isCountRowsSet] ); const toggleAllRowsExpandedRef = React.useRef(void 0); const stateReducer = reducer.useTableStateReducer({ onColumnResize, onSortByChange: (state2) => { toggleAllRowsExpandedRef.current(false); if (props.onSortByChange) { props.onSortByChange(state2); } }, data: data$1 }); const hasUniqueId = !!((_d = (_c = data$1.meta) == null ? void 0 : _c.uniqueRowIdFields) == null ? void 0 : _d.length); const tableHasGeoCell = React.useMemo(() => utils$1.hasGeoCell(data$1), [data$1]); const options = React.useMemo(() => { const options2 = { columns: memoizedColumns, data: memoizedData, disableResizing: !resizable, stateReducer, autoResetPage: false, initialState: reducer.getInitialState(initialSortBy, memoizedColumns), autoResetFilters: false, sortTypes: { // the builtin number type on react-table does not handle NaN values number: utils.sortNumber, // should be replaced with the builtin string when react-table is upgraded, // see https://github.com/tannerlinsley/react-table/pull/3235 "alphanumeric-insensitive": utils.sortCaseInsensitive } }; if (hasUniqueId) { options2.getRowId = (row, relativeIndex) => data.getRowUniqueId(data$1, relativeIndex); options2.autoResetExpanded = false; } return options2; }, [initialSortBy, memoizedColumns, memoizedData, resizable, stateReducer, hasUniqueId, data$1]); const { getTableProps, headerGroups, footerGroups, rows, prepareRow, totalColumnsWidth, page, state, gotoPage, setPageSize, pageOptions, toggleAllRowsExpanded } = reactTable.useTable(options, reactTable.useFilters, reactTable.useSortBy, reactTable.useAbsoluteLayout, reactTable.useResizeColumns, reactTable.useExpanded, reactTable.usePagination); const extendedState = state; toggleAllRowsExpandedRef.current = toggleAllRowsExpanded; React.useEffect(() => { if (!footerOptions) { setFooterItems(footerValues); } }, [footerValues, footerOptions]); React.useEffect(() => { var _a2; if (!footerOptions) { return; } if (!footerOptions.show) { setFooterItems(void 0); return; } if (isCountRowsSet) { const footerItemsCountRows = []; footerItemsCountRows[0] = (_a2 = rows.length.toString()) != null ? _a2 : data$1.length.toString(); setFooterItems(footerItemsCountRows); return; } const footerItems2 = utils.getFooterItems( headerGroups[0].headers, utils.createFooterCalculationValues(rows), footerOptions, theme ); setFooterItems(footerItems2); }, [footerOptions, theme, state.filters, data$1]); let listHeight = height - (headerHeight + footerHeight); if (enablePagination) { listHeight -= tableStyles.cellHeight; } const pageSize = Math.round(listHeight / tableStyles.rowHeight) - 1; React.useEffect(() => { if (pageSize <= 0) { return; } setPageSize(pageSize); }, [pageSize, setPageSize]); React.useEffect(() => { if (data$1.length / pageSize < state.pageIndex) { gotoPage(0); } }, [data$1]); hooks.useResetVariableListSizeCache(extendedState, listRef, data$1, hasUniqueId); hooks.useFixScrollbarContainer(variableSizeListScrollbarRef, tableDivRef); const onNavigate = React.useCallback( (toPage) => { gotoPage(toPage - 1); }, [gotoPage] ); const itemCount = enablePagination ? page.length : rows.length; let paginationEl = null; if (enablePagination) { const itemsRangeStart = state.pageIndex * state.pageSize + 1; let itemsRangeEnd = itemsRangeStart + state.pageSize - 1; const isSmall = width < 550; if (itemsRangeEnd > data$1.length) { itemsRangeEnd = data$1.length; } const numRows = rows.length; const displayedEnd = itemsRangeEnd < rows.length ? itemsRangeEnd : rows.length; paginationEl = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: tableStyles.paginationWrapper, children: [ /* @__PURE__ */ jsxRuntime.jsx( Pagination.Pagination, { currentPage: state.pageIndex + 1, numberOfPages: pageOptions.length, showSmallVersion: isSmall, onNavigate } ), isSmall ? null : /* @__PURE__ */ jsxRuntime.jsx("div", { className: tableStyles.paginationSummary, children: /* @__PURE__ */ jsxRuntime.jsxs(i18n.Trans, { i18nKey: "grafana-ui.table.pagination-summary", children: [ { itemsRangeStart }, " - ", { displayedEnd }, " of ", { numRows }, " rows" ] }) }) ] }); } const longestField = fieldConfig ? utils.guessLongestField(fieldConfig, data$1) : void 0; let textWrapField = void 0; if (fieldConfig !== void 0) { data$1.fields.forEach((field) => { fieldConfig.overrides.forEach((override) => { const matcher = data.getFieldMatcher(override.matcher); if (matcher(field, data$1, [data$1])) { for (const property of override.properties) { if (property.id === "custom.cellOptions" && property.value.wrapText) { textWrapField = field; } } } }); }); } const rendered = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [ /* @__PURE__ */ jsxRuntime.jsxs( "div", { ...getTableProps(), className: tableStyles.table, "aria-label": ariaLabel, role: "table", ref: tableDivRef, style: { width, height }, children: [ /* @__PURE__ */ jsxRuntime.jsx(CustomScrollbar.CustomScrollbar, { hideVerticalTrack: true, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: tableStyles.tableContentWrapper(totalColumnsWidth), children: [ !noHeader && /* @__PURE__ */ jsxRuntime.jsx(HeaderRow.HeaderRow, { headerGroups, showTypeIcons, tableStyles }), itemCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx( "div", { "data-testid": e2eSelectors.selectors.components.Panels.Visualization.Table.body, ref: variableSizeListScrollbarRef, children: /* @__PURE__ */ jsxRuntime.jsx( RowsList.RowsList, { headerGroups, data: data$1, rows, width, cellHeight, headerHeight, rowHeight: tableStyles.rowHeight, itemCount, pageIndex: state.pageIndex, listHeight, listRef, tableState: state, prepareRow, timeRange, onCellFilterAdded, nestedDataField, tableStyles, footerPaginationEnabled: Boolean(enablePagination), enableSharedCrosshair, initialRowIndex, longestField, textWrapField, getActions, replaceVariables, setInspectCell } ) } ) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: height - headerHeight, width }, className: tableStyles.noData, children: noValuesDisplayText }), footerItems && /* @__PURE__ */ jsxRuntime.jsx( FooterRow.FooterRow, { isPaginationVisible: Boolean(enablePagination), footerValues: footerItems, footerGroups, totalColumnsWidth, tableStyles } ) ] }) }), paginationEl ] } ), inspectCell !== null && /* @__PURE__ */ jsxRuntime.jsx( TableCellInspector.TableCellInspector, { mode: inspectCell.mode, value: inspectCell.value, onDismiss: () => { setInspectCell(null); } } ) ] }); if (!tableHasGeoCell) { return rendered; } return /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: rendered, children: /* @__PURE__ */ jsxRuntime.jsx(index.LazyOpenLayersProvider, { children: rendered }) }); }); Table.displayName = "Table"; exports.Table = Table; //# sourceMappingURL=Table.cjs.map