LogContext: Add button to scroll to center (#70821)

add scroll to center button
This commit is contained in:
Sven Grossmann
2023-06-28 14:55:22 +02:00
committed by GitHub
parent bb18fd719a
commit e0619e8aa7
3 changed files with 45 additions and 9 deletions

View File

@@ -7,7 +7,7 @@ import { LogContextButtons } from './LogContextButtons';
describe('LogContextButtons', () => { describe('LogContextButtons', () => {
it('should call onChangeWrapLines when the checkbox is used, case 1', async () => { it('should call onChangeWrapLines when the checkbox is used, case 1', async () => {
const onChangeWrapLines = jest.fn(); const onChangeWrapLines = jest.fn();
render(<LogContextButtons onChangeWrapLines={onChangeWrapLines} />); render(<LogContextButtons onChangeWrapLines={onChangeWrapLines} onScrollCenterClick={jest.fn()} />);
const wrapLinesBox = screen.getByRole('checkbox', { const wrapLinesBox = screen.getByRole('checkbox', {
name: 'Wrap lines', name: 'Wrap lines',
}); });
@@ -18,7 +18,7 @@ describe('LogContextButtons', () => {
it('should call onChangeWrapLines when the checkbox is used, case 2', async () => { it('should call onChangeWrapLines when the checkbox is used, case 2', async () => {
const onChangeWrapLines = jest.fn(); const onChangeWrapLines = jest.fn();
render(<LogContextButtons onChangeWrapLines={onChangeWrapLines} wrapLines />); render(<LogContextButtons onChangeWrapLines={onChangeWrapLines} onScrollCenterClick={jest.fn()} wrapLines />);
const wrapLinesBox = screen.getByRole('checkbox', { const wrapLinesBox = screen.getByRole('checkbox', {
name: 'Wrap lines', name: 'Wrap lines',
}); });
@@ -26,4 +26,12 @@ describe('LogContextButtons', () => {
expect(onChangeWrapLines).toHaveBeenCalledTimes(1); expect(onChangeWrapLines).toHaveBeenCalledTimes(1);
expect(onChangeWrapLines).toHaveBeenCalledWith(false); expect(onChangeWrapLines).toHaveBeenCalledWith(false);
}); });
it('should call onScrollCenterClick when the button is clicked', async () => {
const onScrollCenterClick = jest.fn();
render(<LogContextButtons onChangeWrapLines={jest.fn()} onScrollCenterClick={onScrollCenterClick} />);
const scrollButton = screen.getByRole('button');
await userEvent.click(scrollButton);
expect(onScrollCenterClick).toHaveBeenCalledTimes(1);
});
}); });

View File

@@ -1,15 +1,28 @@
import { css } from '@emotion/css';
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { reportInteraction } from '@grafana/runtime'; import { reportInteraction } from '@grafana/runtime';
import { InlineSwitch } from '@grafana/ui'; import { Button, InlineSwitch, useStyles2 } from '@grafana/ui';
export type Props = { export type Props = {
wrapLines?: boolean; wrapLines?: boolean;
onChangeWrapLines: (wrapLines: boolean) => void; onChangeWrapLines: (wrapLines: boolean) => void;
onScrollCenterClick: () => void;
}; };
function getStyles(theme: GrafanaTheme2) {
return {
buttons: css({
display: 'flex',
gap: theme.spacing(1),
}),
};
}
export const LogContextButtons = (props: Props) => { export const LogContextButtons = (props: Props) => {
const { wrapLines, onChangeWrapLines } = props; const styles = useStyles2(getStyles);
const { wrapLines, onChangeWrapLines, onScrollCenterClick } = props;
const internalOnChangeWrapLines = useCallback( const internalOnChangeWrapLines = useCallback(
(event: React.FormEvent<HTMLInputElement>) => { (event: React.FormEvent<HTMLInputElement>) => {
const state = event.currentTarget.checked; const state = event.currentTarget.checked;
@@ -21,5 +34,12 @@ export const LogContextButtons = (props: Props) => {
[onChangeWrapLines] [onChangeWrapLines]
); );
return <InlineSwitch showLabel value={wrapLines} onChange={internalOnChangeWrapLines} label="Wrap lines" />; return (
<div className={styles.buttons}>
<InlineSwitch showLabel value={wrapLines} onChange={internalOnChangeWrapLines} label="Wrap lines" />
<Button variant="secondary" onClick={onScrollCenterClick}>
Center matched line
</Button>
</div>
);
}; };

View File

@@ -362,6 +362,11 @@ export const LogRowContextModal: React.FunctionComponent<LogRowContextModalProps
}; };
}); // on every render, why not }); // on every render, why not
const scrollToCenter = useCallback(() => {
preEntryElement.current?.scrollIntoView({ block: 'center' });
entryElement.current?.scrollIntoView({ block: 'center' });
}, [preEntryElement, entryElement]);
useLayoutEffect(() => { useLayoutEffect(() => {
const scrollE = scrollElement.current; const scrollE = scrollElement.current;
if (scrollE == null) { if (scrollE == null) {
@@ -373,8 +378,7 @@ export const LogRowContextModal: React.FunctionComponent<LogRowContextModalProps
prevClientHeightRef.current = currentClientHeight; prevClientHeightRef.current = currentClientHeight;
if (prevClientHeight !== currentClientHeight) { if (prevClientHeight !== currentClientHeight) {
// height has changed, we scroll to the center // height has changed, we scroll to the center
preEntryElement.current?.scrollIntoView({ block: 'center' }); scrollToCenter();
entryElement.current?.scrollIntoView({ block: 'center' });
return; return;
} }
@@ -385,7 +389,7 @@ export const LogRowContextModal: React.FunctionComponent<LogRowContextModalProps
const newScrollTop = scrollE.scrollTop + (currentHeight - prevScrollHeight); const newScrollTop = scrollE.scrollTop + (currentHeight - prevScrollHeight);
scrollE.scrollTop = newScrollTop; scrollE.scrollTop = newScrollTop;
} }
}, [context.above.rows]); }, [context.above.rows, scrollToCenter]);
useAsync(updateContextQuery, [getRowContextQuery, row]); useAsync(updateContextQuery, [getRowContextQuery, row]);
@@ -405,7 +409,11 @@ export const LogRowContextModal: React.FunctionComponent<LogRowContextModalProps
)} )}
<div className={cx(styles.flexRow, styles.paddingBottom)}> <div className={cx(styles.flexRow, styles.paddingBottom)}>
<div> <div>
<LogContextButtons wrapLines={wrapLines} onChangeWrapLines={setWrapLines} /> <LogContextButtons
wrapLines={wrapLines}
onChangeWrapLines={setWrapLines}
onScrollCenterClick={scrollToCenter}
/>
</div> </div>
</div> </div>
<div ref={scrollElement} className={styles.logRowGroups}> <div ref={scrollElement} className={styles.logRowGroups}>