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:
@@ -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 (
|
||||
|
||||
Reference in New Issue
Block a user