@grafana/ui
Version:
Grafana Components Library
355 lines (352 loc) • 12.8 kB
JavaScript
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