Log line details: Update styles (#110472)

* LogLineDetails: show border right when controls are disabled

* LogLineDetails: update styles

* Update types in test

* Update background, border, and shadow

* Close details: fix tooltip
This commit is contained in:
Matias Chomicki
2025-09-03 17:44:29 +02:00
committed by GitHub
parent 642d43ff49
commit 9dfd250049
4 changed files with 60 additions and 44 deletions
@@ -67,6 +67,7 @@ const setup = (
onResize: jest.fn(),
timeRange: getDefaultTimeRange(),
timeZone: 'browser',
showControls: true,
...(propOverrides || {}),
};
@@ -581,6 +582,7 @@ describe('LogLineDetails', () => {
logs: [logs[0]],
timeRange: getDefaultTimeRange(),
timeZone: 'browser',
showControls: true,
onResize: jest.fn(),
};
@@ -20,50 +20,53 @@ export interface Props {
timeRange: TimeRange;
timeZone: string;
onResize(): void;
showControls: boolean;
}
export type LogLineDetailsMode = 'inline' | 'sidebar';
export const LogLineDetails = memo(({ containerElement, focusLogLine, logs, timeRange, timeZone, onResize }: Props) => {
const { detailsWidth, noInteractions, setDetailsWidth } = useLogListContext();
const styles = useStyles2(getStyles, 'sidebar');
const dragStyles = useStyles2(getDragStyles);
const containerRef = useRef<HTMLDivElement | null>(null);
export const LogLineDetails = memo(
({ containerElement, focusLogLine, logs, timeRange, timeZone, onResize, showControls }: Props) => {
const { detailsWidth, noInteractions, setDetailsWidth } = useLogListContext();
const styles = useStyles2(getStyles, 'sidebar', showControls);
const dragStyles = useStyles2(getDragStyles);
const containerRef = useRef<HTMLDivElement | null>(null);
const handleResize = useCallback(() => {
if (containerRef.current) {
setDetailsWidth(containerRef.current.clientWidth);
}
onResize();
}, [onResize, setDetailsWidth]);
const handleResize = useCallback(() => {
if (containerRef.current) {
setDetailsWidth(containerRef.current.clientWidth);
}
onResize();
}, [onResize, setDetailsWidth]);
const reportResize = useCallback(() => {
if (containerRef.current && !noInteractions) {
reportInteraction('logs_log_line_details_sidebar_resized', {
width: Math.round(containerRef.current.clientWidth),
});
}
}, [noInteractions]);
const reportResize = useCallback(() => {
if (containerRef.current && !noInteractions) {
reportInteraction('logs_log_line_details_sidebar_resized', {
width: Math.round(containerRef.current.clientWidth),
});
}
}, [noInteractions]);
const maxWidth = containerElement.clientWidth - LOG_LIST_MIN_WIDTH;
const maxWidth = containerElement.clientWidth - LOG_LIST_MIN_WIDTH;
return (
<Resizable
onResize={handleResize}
onResizeStop={reportResize}
handleClasses={{ left: dragStyles.dragHandleVertical }}
defaultSize={{ width: detailsWidth, height: containerElement.clientHeight }}
size={{ width: detailsWidth, height: containerElement.clientHeight }}
enable={{ left: true }}
minWidth={40}
maxWidth={maxWidth}
>
<div className={styles.container} ref={containerRef}>
<LogLineDetailsTabs focusLogLine={focusLogLine} logs={logs} timeRange={timeRange} timeZone={timeZone} />
</div>
</Resizable>
);
});
return (
<Resizable
onResize={handleResize}
onResizeStop={reportResize}
handleClasses={{ left: dragStyles.dragHandleVertical }}
defaultSize={{ width: detailsWidth, height: containerElement.clientHeight }}
size={{ width: detailsWidth, height: containerElement.clientHeight }}
enable={{ left: true }}
minWidth={40}
maxWidth={maxWidth}
>
<div className={styles.container} ref={containerRef}>
<LogLineDetailsTabs focusLogLine={focusLogLine} logs={logs} timeRange={timeRange} timeZone={timeZone} />
</div>
</Resizable>
);
}
);
LogLineDetails.displayName = 'LogLineDetails';
const LogLineDetailsTabs = memo(
@@ -181,7 +184,7 @@ export const InlineLogLineDetails = memo(({ logs, log, onResize, timeRange, time
return (
<div className={`${styles.inlineWrapper} log-line-inline-details`} style={{ maxWidth: detailsWidth }}>
<div className={styles.container}>
<div className={styles.inlineContainer}>
<div className={styles.scrollContainer} ref={scrollRef} onScroll={saveScroll}>
<LogLineDetailsComponent log={log} logs={logs} timeRange={timeRange} timeZone={timeZone} />
</div>
@@ -193,19 +196,29 @@ InlineLogLineDetails.displayName = 'InlineLogLineDetails';
export const LOG_LINE_DETAILS_HEIGHT = 35;
const getStyles = (theme: GrafanaTheme2, mode: LogLineDetailsMode) => ({
const getStyles = (theme: GrafanaTheme2, mode: LogLineDetailsMode, showControls?: boolean) => ({
inlineWrapper: css({
gridColumn: '1 / -1',
height: `${LOG_LINE_DETAILS_HEIGHT}vh`,
padding: theme.spacing(1, 2, 1.5, 2),
marginRight: 1,
}),
container: css({
overflow: 'auto',
inlineContainer: css({
backgroundColor: theme.colors.background.secondary,
border: `1px solid ${theme.colors.border.weak}`,
borderRadius: theme.shape.radius.default,
height: '100%',
boxShadow: theme.shadows.z1,
border: `1px solid ${theme.colors.border.medium}`,
borderRight: mode === 'sidebar' ? 'none' : undefined,
overflow: 'auto',
}),
container: css({
backgroundColor: theme.colors.background.elevated,
border: `1px solid ${theme.colors.border.weak}`,
borderBottomRightRadius: showControls ? undefined : theme.shape.radius.default,
borderRight: mode === 'sidebar' && showControls ? 'none' : undefined,
borderTopRightRadius: showControls ? undefined : theme.shape.radius.default,
boxShadow: theme.shadows.z3,
height: '100%',
overflow: 'auto',
}),
scrollContainer: css({
overflow: 'auto',
@@ -247,7 +247,7 @@ export const LogLineDetailsHeader = ({ focusLogLine, log, search, onSearch }: Pr
/>
<IconButton
name="times"
aria-label={t('logs.log-line-details.close', 'Close log details')}
tooltip={t('logs.log-line-details.close', 'Close log details')}
onClick={closeDetails}
/>
</div>
@@ -423,6 +423,7 @@ const LogListComponent = ({
timeRange={timeRange}
timeZone={timeZone}
onResize={handleLogDetailsResize}
showControls={showControls}
/>
)}
<div className={styles.logListWrapper} ref={wrapperRef}>