grafana/public/app/features/logs/components/LogRowMessageDisplayedFields.tsx
Matias Chomicki 43f4e55a76
LogRowMessageDisplayedFields: sync implementation with LogRowMessage (#71770)
* LogRowMessageDisplayedFields: sync implementation with LogRowMessage

* Add regression test
2023-07-17 18:20:25 +03:00

84 lines
2.5 KiB
TypeScript

import { css } from '@emotion/css';
import React, { useMemo } from 'react';
import { LogRowModel, Field, LinkModel, DataFrame } from '@grafana/data';
import { LogRowMenuCell } from './LogRowMenuCell';
import { LogRowStyles } from './getLogRowStyles';
import { getAllFields } from './logParser';
export interface Props {
row: LogRowModel;
detectedFields: string[];
wrapLogMessage: boolean;
getFieldLinks?: (field: Field, rowIndex: number, dataFrame: DataFrame) => Array<LinkModel<Field>>;
styles: LogRowStyles;
showContextToggle?: (row?: LogRowModel) => boolean;
onOpenContext: (row: LogRowModel) => void;
onPermalinkClick?: (row: LogRowModel) => Promise<void>;
onPinLine?: (row: LogRowModel) => void;
onUnpinLine?: (row: LogRowModel) => void;
pinned?: boolean;
mouseIsOver: boolean;
}
export const LogRowMessageDisplayedFields = React.memo((props: Props) => {
const { row, detectedFields, getFieldLinks, wrapLogMessage, styles, mouseIsOver, pinned, ...rest } = props;
const fields = getAllFields(row, getFieldLinks);
const wrapClassName = wrapLogMessage ? '' : displayedFieldsStyles.noWrap;
// only single key/value rows are filterable, so we only need the first field key for filtering
const line = useMemo(
() =>
detectedFields
.map((parsedKey) => {
const field = fields.find((field) => {
const { keys } = field;
return keys[0] === parsedKey;
});
if (field !== undefined && field !== null) {
return `${parsedKey}=${field.values}`;
}
if (row.labels[parsedKey] !== undefined && row.labels[parsedKey] !== null) {
return `${parsedKey}=${row.labels[parsedKey]}`;
}
return null;
})
.filter((s) => s !== null)
.join(' '),
[detectedFields, fields, row.labels]
);
const shouldShowMenu = useMemo(() => mouseIsOver || pinned, [mouseIsOver, pinned]);
return (
<>
<td className={styles.logsRowMessage}>
<div className={wrapClassName}>{line}</div>
</td>
<td className={`log-row-menu-cell ${styles.logRowMenuCell}`}>
{shouldShowMenu && (
<LogRowMenuCell
logText={line}
row={row}
styles={styles}
pinned={pinned}
{...rest}
mouseIsOver={mouseIsOver}
/>
)}
</td>
</>
);
});
const displayedFieldsStyles = {
noWrap: css`
white-space: nowrap;
`,
};
LogRowMessageDisplayedFields.displayName = 'LogRowMessageDisplayedFields';