UNPKG

@grafana/ui

Version:
355 lines (352 loc) • 12.8 kB
import { css } from '@emotion/css'; import tinycolor from 'tinycolor2'; import { varPreLine } from 'uwrap'; import { FieldType, reduceField, formattedValueToString } from '@grafana/data'; import { TableCellDisplayMode, TableCellHeight, TableCellBackgroundDisplayMode, BarGaugeDisplayMode } from '@grafana/schema'; import '../../../utils/dom.mjs'; import 'react'; import { getTextColorForAlphaBackground } from '../../../utils/colors.mjs'; import 'slate'; import 'lodash'; import '../../../utils/logger.mjs'; import { TABLE } from './constants.mjs'; function getCellHeightCalculator(ctx, lineHeight, defaultRowHeight, padding = 0) { const { count } = varPreLine(ctx); return (text, cellWidth) => { const effectiveCellWidth = Math.max(cellWidth, 20); const TOTAL_PADDING = padding * 2; const numLines = count(text, effectiveCellWidth); const totalHeight = numLines * lineHeight + TOTAL_PADDING; return Math.max(totalHeight, defaultRowHeight); }; } function getDefaultRowHeight(theme, cellHeight) { const bodyFontSize = theme.typography.fontSize; const lineHeight = theme.typography.body.lineHeight; switch (cellHeight) { case TableCellHeight.Sm: return 36; case TableCellHeight.Md: return 42; case TableCellHeight.Lg: return TABLE.MAX_CELL_HEIGHT; } return TABLE.CELL_PADDING * 2 + bodyFontSize * lineHeight; } function getRowHeight(row, calc, avgCharWidth, defaultRowHeight, fieldsData) { let maxLines = 1; let maxLinesCol = ""; for (const key in row) { if (fieldsData.columnTypes[key] === FieldType.string && fieldsData.textWraps[key] && fieldsData.fieldDisplayType[key] !== TableCellDisplayMode.Image) { const cellText = row[key]; if (cellText != null) { const charsPerLine = fieldsData.columnWidths[key] / avgCharWidth; const approxLines = cellText.length / charsPerLine; if (approxLines > maxLines) { maxLines = approxLines; maxLinesCol = key; } } } } return maxLinesCol === "" ? defaultRowHeight : calc(row[maxLinesCol], fieldsData.columnWidths[maxLinesCol]); } function isTextCell(key, columnTypes) { return columnTypes[key] === FieldType.string; } function shouldTextOverflow(key, row, columnTypes, headerCellRefs, ctx, lineHeight, defaultRowHeight, padding, textWrap, field, cellType) { var _a, _b, _c; const cellInspect = (_c = (_b = (_a = field.config) == null ? void 0 : _a.custom) == null ? void 0 : _b.inspect) != null ? _c : false; if (textWrap || cellInspect || cellType === TableCellDisplayMode.Image || !isTextCell(key, columnTypes)) { return false; } return true; } function getTextAlign(field) { if (!field) { return "flex-start"; } if (field.config.custom) { const custom = field.config.custom; switch (custom.align) { case "right": return "flex-end"; case "left": return "flex-start"; case "center": return "center"; } } if (field.type === FieldType.number) { return "flex-end"; } return "flex-start"; } const defaultCellOptions = { type: TableCellDisplayMode.Auto }; function getCellOptions(field) { var _a, _b, _c; if ((_a = field.config.custom) == null ? void 0 : _a.displayMode) { return migrateTableDisplayModeToCellOptions((_b = field.config.custom) == null ? void 0 : _b.displayMode); } if (!((_c = field.config.custom) == null ? void 0 : _c.cellOptions)) { return defaultCellOptions; } return field.config.custom.cellOptions; } function getAlignmentFactor(field, displayValue, rowIndex) { var _a; let alignmentFactor = (_a = field.state) == null ? void 0 : _a.alignmentFactors; if (alignmentFactor) { if (formattedValueToString(alignmentFactor).length < formattedValueToString(displayValue).length) { alignmentFactor = { ...displayValue }; field.state.alignmentFactors = alignmentFactor; } return alignmentFactor; } else { alignmentFactor = { ...displayValue }; const maxIndex = Math.min(field.values.length, rowIndex + 1e3); for (let i = rowIndex + 1; i < maxIndex; i++) { const nextDisplayValue = field.display(field.values[i]); if (formattedValueToString(alignmentFactor).length > formattedValueToString(nextDisplayValue).length) { alignmentFactor.text = displayValue.text; } } if (field.state) { field.state.alignmentFactors = alignmentFactor; } else { field.state = { alignmentFactors: alignmentFactor }; } return alignmentFactor; } } function getFooterItemNG(rows, field, options) { if (options === void 0) { return ""; } if (field.type !== FieldType.number) { return ""; } if (!options.reducer || !options.reducer.length) { return ""; } if (options.fields && options.fields.length > 0) { if (!options.fields.includes(field.name)) { return ""; } } const calc = options.reducer[0]; const value = reduceField({ field: { ...field, values: rows.map((row) => row[getDisplayName(field)]) }, reducers: options.reducer })[calc]; const formattedValue = formattedValueToString(field.display(value)); return formattedValue; } const getFooterStyles = (justifyContent) => ({ footerCell: css({ display: "flex", justifyContent: justifyContent || "space-between" }) }); const CELL_COLOR_DARKENING_MULTIPLIER = 10; const CELL_GRADIENT_DARKENING_MULTIPLIER = 15; const CELL_GRADIENT_HUE_ROTATION_DEGREES = 5; function getCellColors(theme, cellOptions, displayValue) { var _a; const autoCellBackgroundHoverColor = convertRGBAToHex(theme.colors.background.primary, theme.colors.action.hover); const darkeningFactor = theme.isDark ? 1 : -0.7; let textColor = void 0; let bgColor = void 0; let bgHoverColor = autoCellBackgroundHoverColor; if (cellOptions.type === TableCellDisplayMode.ColorText) { textColor = displayValue.color; } else if (cellOptions.type === TableCellDisplayMode.ColorBackground) { const mode = (_a = cellOptions.mode) != null ? _a : TableCellBackgroundDisplayMode.Gradient; if (mode === TableCellBackgroundDisplayMode.Basic) { textColor = getTextColorForAlphaBackground(displayValue.color, theme.isDark); bgColor = tinycolor(displayValue.color).toRgbString(); bgHoverColor = tinycolor(displayValue.color).darken(CELL_COLOR_DARKENING_MULTIPLIER * darkeningFactor).toRgbString(); } else if (mode === TableCellBackgroundDisplayMode.Gradient) { const hoverColor = tinycolor(displayValue.color).darken(CELL_GRADIENT_DARKENING_MULTIPLIER * darkeningFactor).toRgbString(); const bgColor2 = tinycolor(displayValue.color).darken(CELL_COLOR_DARKENING_MULTIPLIER * darkeningFactor).spin(CELL_GRADIENT_HUE_ROTATION_DEGREES); textColor = getTextColorForAlphaBackground(displayValue.color, theme.isDark); bgColor = `linear-gradient(120deg, ${bgColor2.toRgbString()}, ${displayValue.color})`; bgHoverColor = `linear-gradient(120deg, ${bgColor2.toRgbString()}, ${hoverColor})`; } } return { textColor, bgColor, bgHoverColor }; } const extractPixelValue = (spacing) => { return typeof spacing === "number" ? spacing : parseFloat(spacing) || 0; }; const convertRGBAToHex = (backgroundColor, rgbaColor) => { const bg = tinycolor(backgroundColor); const rgba = tinycolor(rgbaColor); return tinycolor.mix(bg, rgba, rgba.getAlpha() * 100).toHexString(); }; const getCellLinks = (field, rowIdx) => { let links; if (field.getLinks) { links = field.getLinks({ valueRowIndex: rowIdx }); } if (!links) { return; } for (let i = 0; i < (links == null ? void 0 : links.length); i++) { if (links[i].onClick) { const origOnClick = links[i].onClick; links[i].onClick = (event) => { if (!(event.ctrlKey || event.metaKey || event.shiftKey)) { event.preventDefault(); origOnClick(event, { field, rowIndex: rowIdx }); } }; } } return links; }; const handleSort = (columnKey, direction, isMultiSort, setSortColumns, sortColumnsRef) => { let currentSortColumn; const updatedSortColumns = sortColumnsRef.current.filter((column) => { const isCurrentColumn = column.columnKey === columnKey; if (isCurrentColumn) { currentSortColumn = column; } return !isCurrentColumn; }); if (currentSortColumn && currentSortColumn.direction === "DESC") { setSortColumns(updatedSortColumns); sortColumnsRef.current = updatedSortColumns; } else { if (isMultiSort) { setSortColumns([...updatedSortColumns, { columnKey, direction }]); sortColumnsRef.current = [...updatedSortColumns, { columnKey, direction }]; } else { setSortColumns([{ columnKey, direction }]); sortColumnsRef.current = [{ columnKey, direction }]; } } }; const frameToRecords = (frame) => { const fnBody = ` const rows = Array(frame.length); const values = frame.fields.map(f => f.values); let rowCount = 0; for (let i = 0; i < frame.length; i++) { rows[rowCount] = { __depth: 0, __index: i, ${frame.fields.map((field, fieldIdx) => `${JSON.stringify(getDisplayName(field))}: values[${fieldIdx}][i]`).join(",")} }; rowCount += 1; if (rows[rowCount-1]['Nested frames']){ const childFrame = rows[rowCount-1]['Nested frames']; rows[rowCount] = {__depth: 1, __index: i, data: childFrame[0]} rowCount += 1; } } return rows; `; const convert = new Function("frame", fnBody); return convert(frame); }; const compare = new Intl.Collator("en", { sensitivity: "base", numeric: true }).compare; function getComparator(sortColumnType) { switch (sortColumnType) { // Handle sorting for frame type fields (sparklines) case FieldType.frame: return (a, b) => { var _a, _b; return ((_a = a == null ? void 0 : a.value) != null ? _a : 0) - ((_b = b == null ? void 0 : b.value) != null ? _b : 0); }; case FieldType.time: case FieldType.number: case FieldType.boolean: return (a, b) => { if (a === b) { return 0; } if (a == null) { return -1; } if (b == null) { return 1; } return Number(a) - Number(b); }; case FieldType.string: case FieldType.enum: default: return (a, b) => compare(String(a != null ? a : ""), String(b != null ? b : "")); } } function migrateTableDisplayModeToCellOptions(displayMode) { switch (displayMode) { // In the case of the gauge we move to a different option case "basic": case "gradient-gauge": case "lcd-gauge": let gaugeMode = BarGaugeDisplayMode.Basic; if (displayMode === "gradient-gauge") { gaugeMode = BarGaugeDisplayMode.Gradient; } else if (displayMode === "lcd-gauge") { gaugeMode = BarGaugeDisplayMode.Lcd; } return { type: TableCellDisplayMode.Gauge, mode: gaugeMode }; // Also true in the case of the color background case "color-background": case "color-background-solid": let mode = TableCellBackgroundDisplayMode.Basic; if (displayMode === "color-background") { mode = TableCellBackgroundDisplayMode.Gradient; } return { type: TableCellDisplayMode.ColorBackground, mode }; default: return { // @ts-ignore type: displayMode }; } } const getIsNestedTable = (dataFrame) => dataFrame.fields.some(({ type }) => type === FieldType.nestedFrames); const processNestedTableRows = (rows, processParents) => { const parentRows = []; const childRows = /* @__PURE__ */ new Map(); rows.forEach((row) => { if (Number(row.__depth) === 0) { parentRows.push(row); } else { childRows.set(Number(row.__index), row); } }); const processedParents = processParents(parentRows); const result = []; processedParents.forEach((row) => { result.push(row); const childRow = childRows.get(Number(row.__index)); if (childRow) { result.push(childRow); } }); return result; }; const getDisplayName = (field) => { var _a, _b; return (_b = (_a = field.state) == null ? void 0 : _a.displayName) != null ? _b : field.name; }; export { convertRGBAToHex, extractPixelValue, frameToRecords, getAlignmentFactor, getCellColors, getCellHeightCalculator, getCellLinks, getCellOptions, getComparator, getDefaultRowHeight, getDisplayName, getFooterItemNG, getFooterStyles, getIsNestedTable, getRowHeight, getTextAlign, handleSort, isTextCell, migrateTableDisplayModeToCellOptions, processNestedTableRows, shouldTextOverflow }; //# sourceMappingURL=utils.mjs.map