@grafana/ui
Version:
Grafana Components Library
337 lines (332 loc) • 11.3 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var jsxRuntime = require('react/jsx-runtime');
var css = require('@emotion/css');
var React = require('react');
var reactWindow = require('react-window');
var rxjs = require('rxjs');
var data = require('@grafana/data');
var schema = require('@grafana/schema');
var ThemeContext = require('../../../themes/ThemeContext.cjs');
var CustomScrollbar = require('../../CustomScrollbar/CustomScrollbar.cjs');
require('../../PanelChrome/index.cjs');
var TableCell = require('../Cells/TableCell.cjs');
var cellUtils = require('../cellUtils.cjs');
var utils = require('../utils.cjs');
var ExpandedRow = require('./ExpandedRow.cjs');
var PanelContext = require('../../PanelChrome/PanelContext.cjs');
;
const RowsList = (props) => {
const {
data: data$1,
rows,
headerHeight,
footerPaginationEnabled,
rowHeight,
itemCount,
pageIndex,
tableState,
prepareRow,
onCellFilterAdded,
width,
cellHeight = schema.TableCellHeight.Sm,
timeRange,
tableStyles,
nestedDataField,
listHeight,
listRef,
enableSharedCrosshair = false,
initialRowIndex = void 0,
headerGroups,
longestField,
textWrapField,
getActions,
replaceVariables,
setInspectCell
} = props;
const [rowHighlightIndex, setRowHighlightIndex] = React.useState(initialRowIndex);
if (initialRowIndex === void 0 && rowHighlightIndex !== void 0) {
setRowHighlightIndex(void 0);
}
const theme = ThemeContext.useTheme2();
const panelContext = PanelContext.usePanelContext();
let osContext = null;
if (window.OffscreenCanvas !== void 0) {
osContext = new OffscreenCanvas(256, 1024).getContext("2d");
}
if (osContext !== void 0 && osContext !== null) {
osContext.font = `${theme.typography.fontSize}px ${theme.typography.body.fontFamily}`;
}
const threshold = React.useMemo(() => {
const timeField = data$1.fields.find((f) => f.type === data.FieldType.time);
if (!timeField) {
return 0;
}
return utils.calculateAroundPointThreshold(timeField);
}, [data$1]);
const onRowHover = React.useCallback(
(idx, frame) => {
if (!panelContext || !enableSharedCrosshair) {
return;
}
const timeField = frame.fields.find((f) => f.type === data.FieldType.time);
if (!timeField) {
return;
}
panelContext.eventBus.publish(
new data.DataHoverEvent({
point: {
time: timeField.values[idx]
}
})
);
},
[enableSharedCrosshair, panelContext]
);
const onRowLeave = React.useCallback(() => {
if (!panelContext || !enableSharedCrosshair) {
return;
}
panelContext.eventBus.publish(new data.DataHoverClearEvent());
}, [enableSharedCrosshair, panelContext]);
const onDataHoverEvent = React.useCallback(
(evt) => {
var _a;
if (((_a = evt.payload.point) == null ? void 0 : _a.time) && evt.payload.rowIndex !== void 0) {
const timeField = data$1.fields.find((f) => f.type === data.FieldType.time);
const time = timeField.values[evt.payload.rowIndex];
const pointTime = evt.payload.point.time;
if (utils.isPointTimeValAroundTableTimeVal(pointTime, time, threshold)) {
setRowHighlightIndex(evt.payload.rowIndex);
return;
}
const matchedRowIndex = timeField.values.findIndex(
(t) => utils.isPointTimeValAroundTableTimeVal(pointTime, t, threshold)
);
if (matchedRowIndex !== -1) {
setRowHighlightIndex(matchedRowIndex);
return;
}
setRowHighlightIndex(void 0);
}
},
[data$1.fields, threshold]
);
React.useEffect(() => {
if (!panelContext || !enableSharedCrosshair || !data.hasTimeField(data$1) || footerPaginationEnabled) {
return;
}
const subs = new rxjs.Subscription();
subs.add(
panelContext.eventBus.getStream(data.DataHoverEvent).pipe(rxjs.debounceTime(250)).subscribe({
next: (evt) => {
if (panelContext.eventBus === evt.origin) {
return;
}
onDataHoverEvent(evt);
}
})
);
subs.add(
panelContext.eventBus.getStream(data.DataHoverClearEvent).pipe(rxjs.debounceTime(250)).subscribe({
next: (evt) => {
if (panelContext.eventBus === evt.origin) {
return;
}
setRowHighlightIndex(void 0);
}
})
);
return () => {
subs.unsubscribe();
};
}, [data$1, enableSharedCrosshair, footerPaginationEnabled, onDataHoverEvent, panelContext]);
let scrollTop = void 0;
if (rowHighlightIndex !== void 0) {
const firstMatchedRowIndex = rows.findIndex((row) => row.index === rowHighlightIndex);
if (firstMatchedRowIndex !== -1) {
scrollTop = headerHeight + (firstMatchedRowIndex - 1) * rowHeight;
}
}
const rowIndexForPagination = React.useCallback(
(index) => {
return tableState.pageIndex * tableState.pageSize + index;
},
[tableState.pageIndex, tableState.pageSize]
);
let rowBg = void 0;
let textWrapFinal;
for (const field of data$1.fields) {
const fieldOptions = field.config.custom;
const cellOptionsExist = fieldOptions !== void 0 && fieldOptions.cellOptions !== void 0;
if (cellOptionsExist && fieldOptions.cellOptions.type === schema.TableCellDisplayMode.ColorBackground && fieldOptions.cellOptions.applyToRow) {
rowBg = (rowIndex) => {
const display = field.display(field.values[rowIndex]);
const colors = cellUtils.getCellColors(tableStyles.theme, fieldOptions.cellOptions, display);
return colors;
};
}
if (textWrapField !== void 0) {
textWrapFinal = textWrapField;
} else if (longestField !== void 0) {
textWrapFinal = longestField;
}
}
const RenderRow = React.useCallback(
({ index, style, rowHighlightIndex: rowHighlightIndex2 }) => {
const indexForPagination = rowIndexForPagination(index);
const row = rows[indexForPagination];
let additionalProps = {};
prepareRow(row);
const expandedRowStyle = tableState.expanded[row.id] ? css.css({ "&:hover": { background: "inherit" } }) : {};
const rowExpanded = nestedDataField && tableState.expanded[row.id];
if (rowHighlightIndex2 !== void 0 && row.index === rowHighlightIndex2) {
style = { ...style, backgroundColor: theme.components.table.rowSelected };
additionalProps = {
"aria-selected": "true"
};
}
if (rowBg) {
const { bgColor, textColor } = rowBg(row.index);
style.background = bgColor;
style.color = textColor;
style.borderLeft = `2px solid ${bgColor}`;
}
if (textWrapFinal) {
const visibleFields = data$1.fields.filter((field) => {
var _a;
return !Boolean((_a = field.config.custom) == null ? void 0 : _a.hidden);
});
const seriesIndex = visibleFields.findIndex((field) => field.name === textWrapFinal.name);
const pxLineHeight = theme.typography.body.lineHeight * theme.typography.fontSize;
const bbox = utils.guessTextBoundingBox(
textWrapFinal.values[row.index],
headerGroups[0].headers[seriesIndex],
osContext,
pxLineHeight,
tableStyles.rowHeight,
tableStyles.cellPadding
);
style.height = bbox.height;
}
const { key, ...rowProps } = row.getRowProps({ style, ...additionalProps });
return /* @__PURE__ */ jsxRuntime.jsxs(
"div",
{
...rowProps,
className: css.cx(tableStyles.row, expandedRowStyle),
onMouseEnter: () => onRowHover(row.index, data$1),
onMouseLeave: onRowLeave,
children: [
rowExpanded && /* @__PURE__ */ jsxRuntime.jsx(
ExpandedRow.ExpandedRow,
{
nestedData: nestedDataField,
tableStyles,
rowIndex: row.index,
width,
cellHeight
}
),
row.cells.map((cell, index2) => /* @__PURE__ */ jsxRuntime.jsx(
TableCell.TableCell,
{
tableStyles,
cell,
onCellFilterAdded,
columnIndex: index2,
columnCount: row.cells.length,
timeRange,
frame: data$1,
rowStyled: rowBg !== void 0,
rowExpanded,
textWrapped: textWrapFinal !== void 0,
height: Number(style.height) - 1,
getActions,
replaceVariables,
setInspectCell
},
index2
))
]
},
key
);
},
[
rowIndexForPagination,
rows,
prepareRow,
tableState.expanded,
nestedDataField,
rowBg,
textWrapFinal,
tableStyles,
onRowLeave,
width,
cellHeight,
theme.components.table.rowSelected,
theme.typography.body.lineHeight,
theme.typography.fontSize,
data$1,
headerGroups,
osContext,
onRowHover,
onCellFilterAdded,
timeRange,
getActions,
replaceVariables,
setInspectCell
]
);
const getItemSize = (index) => {
const indexForPagination = rowIndexForPagination(index);
const row = rows[indexForPagination];
if (tableState.expanded[row.id] && nestedDataField) {
return ExpandedRow.getExpandedRowHeight(nestedDataField, row.index, tableStyles);
}
if (textWrapFinal) {
const visibleFields = data$1.fields.filter((field) => {
var _a;
return !Boolean((_a = field.config.custom) == null ? void 0 : _a.hidden);
});
const seriesIndex = visibleFields.findIndex((field) => field.name === textWrapFinal.name);
const pxLineHeight = theme.typography.fontSize * theme.typography.body.lineHeight;
return utils.guessTextBoundingBox(
textWrapFinal.values[row.index],
headerGroups[0].headers[seriesIndex],
osContext,
pxLineHeight,
tableStyles.rowHeight,
tableStyles.cellPadding
).height;
}
return tableStyles.rowHeight;
};
const handleScroll = (event) => {
const { scrollTop: scrollTop2 } = event.currentTarget;
if (listRef.current !== null) {
listRef.current.scrollTo(scrollTop2);
}
};
React.useEffect(() => {
if (listRef.current) {
listRef.current.resetAfterIndex(0);
}
}, [rows, listRef]);
return /* @__PURE__ */ jsxRuntime.jsx(CustomScrollbar.CustomScrollbar, { onScroll: handleScroll, hideHorizontalTrack: true, scrollTop, children: /* @__PURE__ */ jsxRuntime.jsx(
reactWindow.VariableSizeList,
{
height: listHeight,
itemCount,
itemSize: getItemSize,
width: "100%",
ref: listRef,
style: { overflow: void 0 },
children: ({ index, style }) => RenderRow({ index, style, rowHighlightIndex })
},
`${rowHeight}${pageIndex}`
) });
};
exports.RowsList = RowsList;
//# sourceMappingURL=RowsList.cjs.map