Log details: column sizing and JSON values (#110807)

* LogLineDetails: switch from minmax to fit-content

* LogLineDetailsFields: switch from syntaxHighlighting to prettifyJSON

* Coverage
This commit is contained in:
Matias Chomicki
2025-09-09 18:47:27 +02:00
committed by GitHub
parent 7e8bbd2ec4
commit 09c78e0e9c
3 changed files with 41 additions and 16 deletions
@@ -519,6 +519,36 @@ describe('LogLineDetails', () => {
expect(onClickHideField).toHaveBeenCalledWith('key1');
});
test('Renders JSON field values', async () => {
setup(
undefined,
{ labels: { label1: 'value of label1', label2: '{"key1":"value1", "key2": "value2"}' } },
{ prettifyJSON: false }
);
expect(screen.getByText('label1')).toBeInTheDocument();
expect(screen.getByText('value of label1')).toBeInTheDocument();
expect(screen.getByText('label2')).toBeInTheDocument();
expect(screen.getByText('{"key1":"value1", "key2": "value2"}')).toBeInTheDocument();
});
test('Renders prettify JSON field values', async () => {
setup(
undefined,
{ labels: { label1: 'value of label1', label2: '{"key1":"value1", "key2": "value2"}' } },
{ prettifyJSON: true }
);
expect(screen.getByText('label1')).toBeInTheDocument();
expect(screen.getByText('value of label1')).toBeInTheDocument();
expect(screen.getByText('label2')).toBeInTheDocument();
expect(screen.queryByText('{"key1":"value1", "key2": "value2"}')).not.toBeInTheDocument();
expect(screen.getByText(/key1/)).toBeInTheDocument();
expect(screen.getByText(/value1/)).toBeInTheDocument();
expect(screen.getByText(/key2/)).toBeInTheDocument();
expect(screen.getByText(/value2/)).toBeInTheDocument();
});
test('Exposes buttons to reorder displayed fields', async () => {
const setDisplayedFields = jest.fn();
const onClickHideField = jest.fn();
@@ -103,7 +103,7 @@ const getFieldsStyles = (theme: GrafanaTheme2) => ({
fieldsTable: css({
display: 'grid',
gap: theme.spacing(1),
gridTemplateColumns: `${theme.spacing(11.5)} minmax(auto, 40%) 1fr`,
gridTemplateColumns: `${theme.spacing(11.5)} fit-content(30%) 1fr`,
}),
fieldsTableNoActions: css({
display: 'grid',
@@ -148,7 +148,7 @@ export const LogLineDetailsField = ({
onClickHideField,
onPinLine,
pinLineButtonTooltipTitle,
syntaxHighlighting,
prettifyJSON,
} = useLogListContext();
const styles = useStyles2(getFieldStyles);
@@ -317,7 +317,7 @@ export const LogLineDetailsField = ({
<div className={styles.value}>
<div className={styles.valueContainer}>
{singleValue ? (
<SingleValue value={values[0]} syntaxHighlighting={syntaxHighlighting} />
<SingleValue value={values[0]} prettifyJSON={prettifyJSON} />
) : (
<MultipleValue showCopy={true} values={values} />
)}
@@ -383,6 +383,7 @@ const getFieldStyles = (theme: GrafanaTheme2) => ({
whiteSpace: 'nowrap',
}),
label: css({
paddingRight: theme.spacing(1),
overflowWrap: 'break-word',
wordBreak: 'break-word',
}),
@@ -484,15 +485,9 @@ export const MultipleValue = ({ showCopy, values = [] }: { showCopy?: boolean; v
);
};
export const SingleValue = ({
value: originalValue,
syntaxHighlighting,
}: {
value: string;
syntaxHighlighting?: boolean;
}) => {
export const SingleValue = ({ value: originalValue, prettifyJSON }: { value: string; prettifyJSON?: boolean }) => {
const value = useMemo(() => {
if (!syntaxHighlighting) {
if (!prettifyJSON) {
return originalValue;
}
try {
@@ -502,7 +497,7 @@ export const SingleValue = ({
}
} catch (error) {}
return originalValue;
}, [originalValue, syntaxHighlighting]);
}, [originalValue, prettifyJSON]);
return (
<>
@@ -42,7 +42,7 @@ const getFieldsStyles = (theme: GrafanaTheme2) => ({
linksTable: css({
display: 'grid',
gap: theme.spacing(1),
gridTemplateColumns: `minmax(auto, 40%) 1fr`,
gridTemplateColumns: `fit-content(30%) 1fr`,
marginBottom: theme.spacing(1),
}),
});
@@ -53,7 +53,7 @@ interface LogLineDetailsFieldProps {
}
export const LogLineDetailsField = ({ field, log }: LogLineDetailsFieldProps) => {
const { closeDetails, onPinLine, pinLineButtonTooltipTitle, syntaxHighlighting } = useLogListContext();
const { closeDetails, onPinLine, pinLineButtonTooltipTitle, prettifyJSON } = useLogListContext();
const styles = useStyles2(getFieldStyles);
@@ -65,14 +65,14 @@ export const LogLineDetailsField = ({ field, log }: LogLineDetailsFieldProps) =>
<div className={styles.value}>
<div className={styles.valueContainer}>
{singleValue ? (
<SingleValue value={field.values[0]} syntaxHighlighting={syntaxHighlighting} />
<SingleValue value={field.values[0]} prettifyJSON={prettifyJSON} />
) : (
<MultipleValue showCopy={true} values={field.values} />
)}
</div>
</div>
),
[field.values, singleValue, styles.value, styles.valueContainer, syntaxHighlighting]
[field.values, singleValue, styles.value, styles.valueContainer, prettifyJSON]
);
return (