@grafana/ui
Version:
Grafana Components Library
203 lines (198 loc) • 6.98 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var css = require('@emotion/css');
var i18n = require('@grafana/i18n');
var ThemeContext = require('../../themes/ThemeContext.cjs');
var Button = require('../Button/Button.cjs');
var Icon = require('../Icon/Icon.cjs');
var hooks = require('../List/hooks.cjs');
var VizLegendTableItem = require('./VizLegendTableItem.cjs');
"use strict";
const nameSortKey = "Name";
const naturalCompare = new Intl.Collator(void 0, { numeric: true, sensitivity: "base" }).compare;
const VizLegendTable = ({
items,
sortBy: sortKey,
sortDesc,
itemRenderer,
className,
onToggleSort,
onLabelClick,
onLabelMouseOver,
onLabelMouseOut,
readonly,
isSortable,
limit = 0,
filterAction,
placement,
overflow
}) => {
var _a, _b;
const styles = ThemeContext.useStyles2(getStyles, placement);
const header = {
[nameSortKey]: ""
};
for (const item of items) {
if (item.getDisplayValues) {
for (const displayValue of item.getDisplayValues()) {
header[(_a = displayValue.title) != null ? _a : "?"] = (_b = displayValue.description) != null ? _b : "";
}
}
}
if (sortKey != null) {
let itemVals = /* @__PURE__ */ new Map();
items.forEach((item) => {
if (sortKey !== nameSortKey && item.getDisplayValues) {
const stat = item.getDisplayValues().find((stat2) => stat2.title === sortKey);
const val = stat == null || Number.isNaN(stat.numeric) ? -Infinity : stat.numeric;
itemVals.set(item, val);
}
});
let sortMult = sortDesc ? -1 : 1;
if (sortKey === nameSortKey) {
items.sort((a, b) => {
return sortMult * naturalCompare(a.label, b.label);
});
} else {
items.sort((a, b) => {
var _a2, _b2;
const aVal = (_a2 = itemVals.get(a)) != null ? _a2 : 0;
const bVal = (_b2 = itemVals.get(b)) != null ? _b2 : 0;
return sortMult * (aVal - bVal);
});
}
}
const [curLimit, setLimit] = hooks.useLimit(limit);
const limitedItems = React.useMemo(() => curLimit > 0 ? items.slice(0, curLimit) : items, [items, curLimit]);
const hasMixedAxes = React.useMemo(() => {
var _a2, _b2;
const firstYAxis = (_b2 = (_a2 = items[0]) == null ? void 0 : _a2.yAxis) != null ? _b2 : 1;
return items.some((item) => item.yAxis !== firstYAxis);
}, [items]);
if (!itemRenderer) {
itemRenderer = (item, index) => /* @__PURE__ */ jsxRuntime.jsx(
VizLegendTableItem.LegendTableItem,
{
item,
onLabelClick,
onLabelMouseOver,
onLabelMouseOut,
readonly,
hasMixedAxes,
overflow
},
`${item.label}-${index}`
);
}
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsxs(
"table",
{
className: css.cx(styles.grid, className),
style: {
gridTemplateColumns: `min-content minmax(55px, auto) ${"min-content ".repeat(Object.keys(header).length - 1)}`
},
children: [
/* @__PURE__ */ jsxRuntime.jsx("thead", { className: styles.header, children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
/* @__PURE__ */ jsxRuntime.jsx("th", { children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: /* @__PURE__ */ jsxRuntime.jsx(i18n.Trans, { i18nKey: "legend.container.series-color-and-icon", children: "Series color" }) }) }),
Object.keys(header).map((columnTitle, i) => /* @__PURE__ */ React.createElement(
"th",
{
...sortKey === columnTitle ? { "aria-sort": sortDesc ? "descending" : "ascending" } : null,
title: header[columnTitle],
key: columnTitle,
className: css.cx({
[styles.headerSortable]: Boolean(onToggleSort),
[styles.nameHeader]: isSortable,
[styles.calcHeader]: i > 0,
[styles.withIcon]: sortKey === columnTitle,
"sr-only": !isSortable
}),
onClick: () => {
if (onToggleSort && isSortable) {
onToggleSort(columnTitle);
}
}
},
columnTitle === nameSortKey && filterAction && // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
/* @__PURE__ */ jsxRuntime.jsx("span", { className: styles.filterAction, onClick: (e) => e.stopPropagation(), children: filterAction }),
columnTitle,
sortKey === columnTitle && /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { size: "xs", name: sortDesc ? "angle-down" : "angle-up" })
))
] }) }),
/* @__PURE__ */ jsxRuntime.jsx("tbody", { children: limitedItems.map(itemRenderer) })
]
}
),
curLimit > 0 && items.length > curLimit && /* @__PURE__ */ jsxRuntime.jsx(Button.Button, { fill: "text", variant: "primary", size: "sm", onClick: () => setLimit(0), className: styles.showAll, children: /* @__PURE__ */ jsxRuntime.jsxs(i18n.Trans, { i18nKey: "legend.container.show-all-series", className: styles.showAll, children: [
"...show all ",
{ total: items.length },
" items"
] }) })
] });
};
const getStyles = (theme, placement = "bottom") => ({
header: css.css({
position: "sticky",
top: 0,
backgroundColor: theme.colors.background.primary,
color: theme.colors.primary.text
}),
nameHeader: css.css({
textAlign: "left"
}),
calcHeader: css.css({
textAlign: "right"
}),
withIcon: css.css({
paddingRight: "4px"
}),
headerSortable: css.css({
cursor: "pointer"
}),
filterAction: css.css({
marginLeft: theme.spacing(0.5),
display: "inline-flex",
verticalAlign: "middle"
}),
showAll: css.css({
justifyContent: "right"
}),
grid: css.css({
display: "grid",
width: "100%",
// non-layout
fontSize: theme.typography.bodySmall.fontSize,
textAlign: "right",
whiteSpace: "nowrap",
"tbody,thead,tfoot,tr": {
display: "grid",
gridColumn: "1 / -1",
gridTemplateColumns: "subgrid"
},
tr: {
borderBottom: `1px solid ${theme.colors.border.weak}`
},
"th,td": {
display: "block",
alignContent: "center",
whiteSpace: "nowrap",
// non-layout
padding: theme.spacing(0.25, 1),
// series color/icon column
"&:nth-child(1)": {
paddingLeft: theme.spacing(1)
},
// series name column
"&:nth-child(2)": {
overflow: "hidden",
textOverflow: "ellipsis",
maxWidth: placement === "right" ? 600 : void 0
}
}
})
});
exports.VizLegendTable = VizLegendTable;
//# sourceMappingURL=VizLegendTable.cjs.map