import { css, cx } from '@emotion/css';
import { memo, forwardRef, useMemo } from 'react';
import { GrafanaTheme2, Labels } from '@grafana/data';
import { Tooltip, useStyles2 } from '@grafana/ui';
import { LOG_LINE_BODY_FIELD_NAME } from './LogDetailsBody';
// Levels are already encoded in color, filename is a Loki-ism
const HIDDEN_LABELS = ['detected_level', 'level', 'lvl', 'filename'];
interface Props {
labels: Labels;
emptyMessage?: string;
addTooltip?: boolean;
}
export const LogLabels = memo(({ labels, emptyMessage, addTooltip = true }: Props) => {
const styles = useStyles2(getStyles);
const displayLabels = useMemo(
() =>
Object.keys(labels)
.filter((label) => !label.startsWith('_') && !HIDDEN_LABELS.includes(label) && labels[label])
.map((label) => `${label}=${labels[label]}`),
[labels]
);
if (displayLabels.length === 0 && emptyMessage) {
return (
{emptyMessage}
);
}
return (
{displayLabels.map((labelValue) => {
return addTooltip ? (
{labelValue}
) : (
{labelValue}
);
})}
);
});
LogLabels.displayName = 'LogLabels';
interface LogLabelsArrayProps {
labels: string[];
}
export const LogLabelsList = memo(({ labels }: LogLabelsArrayProps) => {
const styles = useStyles2(getStyles);
return (
{labels.map((label) => (
{label === LOG_LINE_BODY_FIELD_NAME ? 'log line' : label}
))}
);
});
LogLabelsList.displayName = 'LogLabelsList';
interface LogLabelProps {
styles: Record;
tooltip?: string;
children: JSX.Element | string;
}
const LogLabel = forwardRef(({ styles, tooltip, children }: LogLabelProps, ref) => {
return (
{children}
);
});
LogLabel.displayName = 'LogLabel';
const getStyles = (theme: GrafanaTheme2) => {
return {
logsLabels: css({
display: 'flex',
flexWrap: 'wrap',
fontSize: theme.typography.size.xs,
}),
logsLabel: css({
label: 'logs-label',
display: 'flex',
padding: theme.spacing(0, 0.25),
backgroundColor: theme.colors.background.secondary,
borderRadius: theme.shape.radius.default,
margin: theme.spacing(0.125, 0.5, 0, 0),
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
}),
logsLabelValue: css({
label: 'logs-label__value',
display: 'inline-block',
maxWidth: theme.spacing(25),
textOverflow: 'ellipsis',
overflow: 'hidden',
}),
};
};