grafana/public/app/features/logs/components/LogRowMessageDisplayedFields.tsx
Matias Chomicki b8fbeb084a
Logs: Display log row menu cell on displayed fields (#71300)
* LogRowMenuCell: create component

* LogRowMessage: use new LogRowMenuCell component

* LogRowMessage: turn into functional component

* LogRowMenuCell: memoize component

* LogRowMessage: remove cx

* LogMessage: create component from function

* LogRowMessageDisplayedFields: turn into component

* LogRowMessageDisplayedFields: add LogRowMenuCell

* LogRowMessageDisplayedFields: rename prop and pass missing context prop

* LogRowMessageDisplayedFields: add unit test
2023-07-11 14:50:53 +02:00

68 lines
2.1 KiB
TypeScript

import { css } from '@emotion/css';
import React 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;
}
export const LogRowMessageDisplayedFields = React.memo((props: Props) => {
const { row, detectedFields, getFieldLinks, wrapLogMessage, styles, ...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 = 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(' ');
return (
<>
<td className={styles.logsRowMessage}>
<div className={wrapClassName}>{line}</div>
</td>
<td className={`log-row-menu-cell ${styles.logRowMenuCell}`}>
<LogRowMenuCell logText={line} row={row} styles={styles} {...rest} />
</td>
</>
);
});
const displayedFieldsStyles = {
noWrap: css`
white-space: nowrap;
`,
};
LogRowMessageDisplayedFields.displayName = 'LogRowMessageDisplayedFields';