mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
Explore: Fix showing of full log context (#37442)
* Fix log context * Update to auto values insted of unset * Update comment * Fix redundant left margin for non-wrapped logs * Remove unused css styling * Adjust width and height
This commit is contained in:
parent
7e63118ea9
commit
a02f9be0c6
@ -4,7 +4,7 @@ import { css, cx } from '@emotion/css';
|
||||
|
||||
import { Alert } from '../Alert/Alert';
|
||||
import { LogRowContextRows, LogRowContextQueryErrors, HasMoreContextRows } from './LogRowContextProvider';
|
||||
import { useStyles } from '../../themes/ThemeContext';
|
||||
import { useStyles, useTheme } from '../../themes/ThemeContext';
|
||||
import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar';
|
||||
import { List } from '../List/List';
|
||||
import { ClickOutsideWrapper } from '../ClickOutsideWrapper/ClickOutsideWrapper';
|
||||
@ -13,18 +13,41 @@ import { LogMessageAnsi } from './LogMessageAnsi';
|
||||
interface LogRowContextProps {
|
||||
row: LogRowModel;
|
||||
context: LogRowContextRows;
|
||||
wrapLogMessage: boolean;
|
||||
errors?: LogRowContextQueryErrors;
|
||||
hasMoreContextRows?: HasMoreContextRows;
|
||||
onOutsideClick: () => void;
|
||||
onLoadMoreContext: () => void;
|
||||
}
|
||||
|
||||
const getLogRowContextStyles = (theme: GrafanaTheme) => {
|
||||
const getLogRowContextStyles = (theme: GrafanaTheme, wrapLogMessage?: boolean) => {
|
||||
/**
|
||||
* This is workaround for displaying uncropped context when we have unwrapping log messages.
|
||||
* We are using margins to correctly position context. Because non-wrapped logs have always 1 line of log
|
||||
* and 1 line of Show/Hide context switch. Therefore correct position can be reliably achieved by margins.
|
||||
* We also adjust width to 75%.
|
||||
*/
|
||||
|
||||
const afterContext = wrapLogMessage
|
||||
? css`
|
||||
top: -250px;
|
||||
`
|
||||
: css`
|
||||
margin-top: -250px;
|
||||
width: 75%;
|
||||
`;
|
||||
|
||||
const beforeContext = wrapLogMessage
|
||||
? css`
|
||||
top: 100%;
|
||||
`
|
||||
: css`
|
||||
margin-top: 40px;
|
||||
width: 75%;
|
||||
`;
|
||||
return {
|
||||
commonStyles: css`
|
||||
position: absolute;
|
||||
width: calc(100% + 20px);
|
||||
left: -13px;
|
||||
height: 250px;
|
||||
z-index: ${theme.zIndex.dropdown};
|
||||
overflow: hidden;
|
||||
@ -32,6 +55,7 @@ const getLogRowContextStyles = (theme: GrafanaTheme) => {
|
||||
box-shadow: 0 0 10px ${theme.colors.dropdownShadow};
|
||||
border: 1px solid ${theme.colors.bg2};
|
||||
border-radius: ${theme.border.radius.md};
|
||||
width: 100%;
|
||||
`,
|
||||
header: css`
|
||||
height: 30px;
|
||||
@ -44,6 +68,8 @@ const getLogRowContextStyles = (theme: GrafanaTheme) => {
|
||||
height: 220px;
|
||||
padding: 10px;
|
||||
`,
|
||||
afterContext,
|
||||
beforeContext,
|
||||
};
|
||||
};
|
||||
|
||||
@ -56,7 +82,7 @@ interface LogRowContextGroupHeaderProps {
|
||||
}
|
||||
interface LogRowContextGroupProps extends LogRowContextGroupHeaderProps {
|
||||
rows: Array<string | DataQueryError>;
|
||||
className: string;
|
||||
className?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
@ -122,11 +148,11 @@ export const LogRowContextGroup: React.FunctionComponent<LogRowContextGroupProps
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cx(className, commonStyles)}>
|
||||
<div className={cx(commonStyles, className)}>
|
||||
{/* When displaying "after" context */}
|
||||
{shouldScrollToBottom && !error && <LogRowContextGroupHeader {...headerProps} />}
|
||||
<div className={logs}>
|
||||
<CustomScrollbar autoHide scrollTop={scrollTop}>
|
||||
<CustomScrollbar autoHide scrollTop={scrollTop} autoHeightMin={'210px'}>
|
||||
<div ref={listContainerRef}>
|
||||
{!error && (
|
||||
<List
|
||||
@ -161,6 +187,7 @@ export const LogRowContext: React.FunctionComponent<LogRowContextProps> = ({
|
||||
onOutsideClick,
|
||||
onLoadMoreContext,
|
||||
hasMoreContextRows,
|
||||
wrapLogMessage,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
const handleEscKeyDown = (e: KeyboardEvent): void => {
|
||||
@ -173,6 +200,8 @@ export const LogRowContext: React.FunctionComponent<LogRowContextProps> = ({
|
||||
document.removeEventListener('keydown', handleEscKeyDown, false);
|
||||
};
|
||||
}, [onOutsideClick]);
|
||||
const theme = useTheme();
|
||||
const { afterContext, beforeContext } = getLogRowContextStyles(theme, wrapLogMessage);
|
||||
|
||||
return (
|
||||
<ClickOutsideWrapper onClick={onOutsideClick}>
|
||||
@ -184,9 +213,7 @@ export const LogRowContext: React.FunctionComponent<LogRowContextProps> = ({
|
||||
rows={context.after}
|
||||
error={errors && errors.after}
|
||||
row={row}
|
||||
className={css`
|
||||
top: -250px;
|
||||
`}
|
||||
className={afterContext}
|
||||
shouldScrollToBottom
|
||||
canLoadMoreRows={hasMoreContextRows ? hasMoreContextRows.after : false}
|
||||
onLoadMoreContext={onLoadMoreContext}
|
||||
@ -200,9 +227,7 @@ export const LogRowContext: React.FunctionComponent<LogRowContextProps> = ({
|
||||
row={row}
|
||||
rows={context.before}
|
||||
error={errors && errors.before}
|
||||
className={css`
|
||||
top: 100%;
|
||||
`}
|
||||
className={beforeContext}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
@ -51,6 +51,10 @@ const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
label: verticalScroll;
|
||||
white-space: pre;
|
||||
`,
|
||||
contextNewline: css`
|
||||
display: block;
|
||||
margin-left: 0px;
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
@ -124,12 +128,15 @@ class UnThemedLogRowMessage extends PureComponent<Props> {
|
||||
|
||||
return (
|
||||
<td className={style.logsRowMessage}>
|
||||
<div className={cx(styles.positionRelative, { [styles.horizontalScroll]: !wrapLogMessage })}>
|
||||
<div
|
||||
className={cx({ [styles.positionRelative]: wrapLogMessage }, { [styles.horizontalScroll]: !wrapLogMessage })}
|
||||
>
|
||||
{contextIsOpen && context && (
|
||||
<LogRowContext
|
||||
row={row}
|
||||
context={context}
|
||||
errors={errors}
|
||||
wrapLogMessage={wrapLogMessage}
|
||||
hasMoreContextRows={hasMoreContextRows}
|
||||
onOutsideClick={onToggleContext}
|
||||
onLoadMoreContext={() => {
|
||||
@ -143,7 +150,10 @@ class UnThemedLogRowMessage extends PureComponent<Props> {
|
||||
{renderLogMessage(hasAnsi, restructuredEntry, highlights, highlightClassName)}
|
||||
</span>
|
||||
{showContextToggle?.(row) && (
|
||||
<span onClick={this.onContextToggle} className={cx('log-row-context', style.context)}>
|
||||
<span
|
||||
onClick={this.onContextToggle}
|
||||
className={cx('log-row-context', style.context, { [styles.contextNewline]: !wrapLogMessage })}
|
||||
>
|
||||
{contextIsOpen ? 'Hide' : 'Show'} context
|
||||
</span>
|
||||
)}
|
||||
|
@ -48,13 +48,13 @@ export const getLogRowStyles = stylesFactory((theme: GrafanaTheme, logLevel?: Lo
|
||||
font-family: ${theme.typography.fontFamily.monospace};
|
||||
font-size: ${theme.typography.size.sm};
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
`,
|
||||
context: css`
|
||||
label: context;
|
||||
visibility: hidden;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
margin-left: 10px;
|
||||
`,
|
||||
logsRow: css`
|
||||
label: logs-row;
|
||||
@ -66,7 +66,6 @@ export const getLogRowStyles = stylesFactory((theme: GrafanaTheme, logLevel?: Lo
|
||||
.log-row-context {
|
||||
visibility: visible;
|
||||
z-index: 1;
|
||||
margin-left: 10px;
|
||||
text-decoration: underline;
|
||||
&:hover {
|
||||
color: ${theme.palette.yellow};
|
||||
|
@ -283,7 +283,7 @@ export class UnthemedLogs extends PureComponent<Props, State> {
|
||||
forceEscape,
|
||||
} = this.state;
|
||||
|
||||
const styles = getStyles(theme);
|
||||
const styles = getStyles(theme, wrapLogMessage);
|
||||
const hasData = logRows && logRows.length > 0;
|
||||
const hasUnescapedContent = this.checkUnescapedContent(logRows);
|
||||
|
||||
@ -420,7 +420,7 @@ export class UnthemedLogs extends PureComponent<Props, State> {
|
||||
|
||||
export const Logs = withTheme2(UnthemedLogs);
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => {
|
||||
const getStyles = (theme: GrafanaTheme2, wrapLogMessage: boolean) => {
|
||||
return {
|
||||
noData: css`
|
||||
> * {
|
||||
@ -450,7 +450,8 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
justify-content: space-between;
|
||||
`,
|
||||
logRows: css`
|
||||
overflow-x: scroll;
|
||||
overflow-x: ${wrapLogMessage ? 'unset' : 'scroll'};
|
||||
overflow-y: visible;
|
||||
width: 100%;
|
||||
`,
|
||||
infoText: css`
|
||||
|
Loading…
Reference in New Issue
Block a user