UNPKG

@grafana/ui

Version:
166 lines (163 loc) • 6.35 kB
import { jsxs, jsx } from 'react/jsx-runtime'; import { cx, css } from '@emotion/css'; import { useState, useCallback } from 'react'; import { FIELD_NAME_FACET_KEY } from '@grafana/data'; import { Trans } from '@grafana/i18n'; import { useStyles2 } from '../../themes/ThemeContext.mjs'; import { Checkbox } from '../Forms/Checkbox.mjs'; import { Icon } from '../Icon/Icon.mjs'; "use strict"; function FacetedLabelsFilter({ labels, selected, onChange, dimmed }) { const styles = useStyles2(getStyles); const [expandedKeys, setExpandedKeys] = useState({}); const labelKeys = Object.keys(labels); const toggleExpanded = useCallback((key) => { setExpandedKeys((prev) => ({ ...prev, [key]: !prev[key] })); }, []); const toggleValue = useCallback( (key, value) => { var _a; const current = (_a = selected[key]) != null ? _a : []; const next = current.includes(value) ? current.filter((v) => v !== value) : [...current, value]; onChange({ ...selected, [key]: next }); }, [selected, onChange] ); const toggleAllForKey = useCallback( (key) => { var _a; const values = labels[key]; if (!values) { return; } const current = (_a = selected[key]) != null ? _a : []; const allSelected = current.length === values.length; onChange({ ...selected, [key]: allSelected ? [] : [...values] }); }, [labels, selected, onChange] ); const seriesValues = labels[FIELD_NAME_FACET_KEY]; const realLabelKeys = labelKeys.filter((key) => key !== FIELD_NAME_FACET_KEY); if (!seriesValues && realLabelKeys.length === 0) { return null; } const renderCheckboxList = (key, values, className) => { var _a; const selectedValues = (_a = selected[key]) != null ? _a : []; return /* @__PURE__ */ jsxs("div", { className, children: [ values.map((value) => /* @__PURE__ */ jsx( Checkbox, { label: value, value: selectedValues.includes(value), onChange: () => toggleValue(key, value), className: styles.checkbox }, value )), /* @__PURE__ */ jsx("button", { type: "button", className: styles.toggleAll, onClick: () => toggleAllForKey(key), children: selectedValues.length === values.length ? /* @__PURE__ */ jsx(Trans, { i18nKey: "grafana-ui.viz-legend.faceted-deselect-all", children: "Deselect all" }) : /* @__PURE__ */ jsx(Trans, { i18nKey: "grafana-ui.viz-legend.faceted-select-all", children: "Select all" }) }) ] }); }; return /* @__PURE__ */ jsxs("div", { className: cx(styles.container, dimmed && styles.dimmed), "data-testid": "faceted-labels-filter", children: [ seriesValues && /* @__PURE__ */ jsxs("div", { className: styles.section, children: [ /* @__PURE__ */ jsx("span", { className: styles.sectionLabel, children: /* @__PURE__ */ jsx(Trans, { i18nKey: "grafana-ui.viz-legend.faceted-by-name", children: "By name" }) }), renderCheckboxList(FIELD_NAME_FACET_KEY, seriesValues, styles.checkboxList) ] }), realLabelKeys.length > 0 && /* @__PURE__ */ jsxs("div", { className: styles.section, children: [ /* @__PURE__ */ jsx("span", { className: styles.sectionLabel, children: /* @__PURE__ */ jsx(Trans, { i18nKey: "grafana-ui.viz-legend.faceted-by-labels", children: "By labels" }) }), realLabelKeys.map((key) => { var _a, _b; const selectedValues = (_a = selected[key]) != null ? _a : []; const isExpanded = (_b = expandedKeys[key]) != null ? _b : false; return /* @__PURE__ */ jsxs("div", { className: styles.labelGroup, children: [ /* @__PURE__ */ jsxs("button", { type: "button", className: styles.labelKey, onClick: () => toggleExpanded(key), children: [ /* @__PURE__ */ jsx(Icon, { name: isExpanded ? "angle-down" : "angle-right", size: "sm" }), /* @__PURE__ */ jsx("span", { className: styles.keyName, children: key }), selectedValues.length > 0 && /* @__PURE__ */ jsx("span", { className: styles.count, children: selectedValues.length }) ] }), isExpanded && renderCheckboxList(key, labels[key], styles.checkboxListIndented) ] }, key); }) ] }) ] }); } FacetedLabelsFilter.displayName = "FacetedLabelsFilter"; const getStyles = (theme) => ({ container: css({ display: "flex", flexDirection: "column", alignItems: "stretch", minWidth: "150px", padding: theme.spacing(1.5, 1, 1, 1), gap: theme.spacing(1) }), dimmed: css({ opacity: 0.5 }), section: css({ display: "flex", flexDirection: "column" }), sectionLabel: css({ fontSize: theme.typography.bodySmall.fontSize, fontWeight: theme.typography.fontWeightMedium, color: theme.colors.text.secondary, marginBottom: theme.spacing(0.25) }), toggleAll: css({ all: "unset", cursor: "pointer", fontSize: theme.typography.bodySmall.fontSize, color: theme.colors.text.link, marginTop: theme.spacing(0.25), "&:hover": { textDecoration: "underline" } }), labelGroup: css({ display: "flex", flexDirection: "column" }), labelKey: css({ all: "unset", display: "flex", alignItems: "center", gap: theme.spacing(0.5), cursor: "pointer", padding: theme.spacing(0.25, 0), fontSize: theme.typography.bodySmall.fontSize, color: theme.colors.text.primary, "&:hover": { color: theme.colors.text.maxContrast } }), keyName: css({ fontWeight: theme.typography.fontWeightMedium, fontFamily: theme.typography.fontFamilyMonospace }), count: css({ fontSize: theme.typography.bodySmall.fontSize, color: theme.colors.primary.text, fontWeight: theme.typography.fontWeightMedium }), checkboxList: css({ display: "flex", flexDirection: "column", alignItems: "flex-start", gap: theme.spacing(0.25), padding: theme.spacing(0, 0, 0.5, 0.5) }), checkboxListIndented: css({ display: "flex", flexDirection: "column", alignItems: "flex-start", gap: theme.spacing(0.25), padding: theme.spacing(0, 0, 0.5, 2.5) }), checkbox: css({ fontSize: theme.typography.bodySmall.fontSize, fontFamily: theme.typography.fontFamilyMonospace }) }); export { FacetedLabelsFilter }; //# sourceMappingURL=FacetedLabelsFilter.mjs.map