mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-03 19:16:10 +00:00
Fix the logs after call not triggering when scrolled to bottom (#22617)
This commit is contained in:
parent
787ab807b1
commit
6b2b8d2ea0
@ -36,6 +36,7 @@ import {
|
||||
getExternalApplicationRuns,
|
||||
getLatestApplicationRuns,
|
||||
} from '../../rest/applicationAPI';
|
||||
import { getIngestionPipelineLogById } from '../../rest/ingestionPipelineAPI';
|
||||
import LogsViewerPage from './LogsViewerPage';
|
||||
|
||||
const mockScrollToIndex = jest.fn();
|
||||
@ -106,24 +107,53 @@ jest.mock('../../hooks/useDownloadProgressStore', () => ({
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('@melloware/react-logviewer', () => ({
|
||||
LazyLog: React.forwardRef(({ text }: { text: string }, ref) => {
|
||||
// Mock the ref structure that the component expects
|
||||
if (ref) {
|
||||
(ref as { current: Record<string, unknown> }).current = {
|
||||
state: {
|
||||
count: 230,
|
||||
},
|
||||
listRef: {
|
||||
current: {
|
||||
scrollToIndex: mockScrollToIndex,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
let mockScrollPosition = {
|
||||
scrollTop: 80,
|
||||
scrollHeight: 100,
|
||||
clientHeight: 20,
|
||||
};
|
||||
|
||||
return <div data-testid="lazy-log">{text}</div>;
|
||||
}),
|
||||
jest.mock('@melloware/react-logviewer', () => ({
|
||||
LazyLog: React.forwardRef(
|
||||
(
|
||||
{
|
||||
text,
|
||||
onScroll,
|
||||
}: {
|
||||
text: string;
|
||||
onScroll: (args: {
|
||||
scrollTop: number;
|
||||
scrollHeight: number;
|
||||
clientHeight: number;
|
||||
}) => void;
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
// Mock the ref structure that the component expects
|
||||
if (ref) {
|
||||
(ref as { current: Record<string, unknown> }).current = {
|
||||
state: {
|
||||
count: 230,
|
||||
},
|
||||
listRef: {
|
||||
current: {
|
||||
scrollToIndex: mockScrollToIndex,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<div data-testid="lazy-log">
|
||||
{text}
|
||||
<div
|
||||
data-testid="scroll-container"
|
||||
onClick={() => onScroll(mockScrollPosition)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
),
|
||||
}));
|
||||
|
||||
describe('LogsViewerPage.component', () => {
|
||||
@ -198,4 +228,138 @@ describe('LogsViewerPage.component', () => {
|
||||
// Verify that scrollToIndex was called with the correct parameter (totalLines - 1)
|
||||
expect(mockScrollToIndex).toHaveBeenCalledWith(229);
|
||||
});
|
||||
|
||||
it('should call handleScroll when user scrolls at the bottom', async () => {
|
||||
(useParams as jest.Mock).mockReturnValue({
|
||||
logEntityType: 'TestSuite',
|
||||
ingestionName: 'ingestion_123456',
|
||||
});
|
||||
await act(async () => {
|
||||
render(<LogsViewerPage />);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('scroll-container')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const scrollContainer = screen.getByTestId('scroll-container');
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(scrollContainer);
|
||||
});
|
||||
|
||||
expect(getIngestionPipelineLogById).toHaveBeenCalledWith(
|
||||
'c379d75a-43cd-4d93-a799-0bba4a22c690',
|
||||
'1'
|
||||
);
|
||||
});
|
||||
|
||||
it('should not call handleScroll when user scrolls and is not at the bottom', async () => {
|
||||
// Set scroll position to NOT be at the bottom
|
||||
mockScrollPosition = { scrollTop: 10, scrollHeight: 100, clientHeight: 20 };
|
||||
|
||||
await act(async () => {
|
||||
render(<LogsViewerPage />);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('scroll-container')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const scrollContainer = screen.getByTestId('scroll-container');
|
||||
|
||||
// Simulate scroll that is NOT at the bottom
|
||||
await act(async () => {
|
||||
fireEvent.click(scrollContainer);
|
||||
});
|
||||
|
||||
// Verify that the API was not called since we're not at the bottom
|
||||
expect(getIngestionPipelineLogById).not.toHaveBeenCalledWith(
|
||||
'c379d75a-43cd-4d93-a799-0bba4a22c690',
|
||||
'1'
|
||||
);
|
||||
});
|
||||
|
||||
it('should not call handleScroll when user scrolls and is at the bottom with 40- margin', async () => {
|
||||
mockScrollPosition = { scrollTop: 41, scrollHeight: 100, clientHeight: 20 };
|
||||
|
||||
await act(async () => {
|
||||
render(<LogsViewerPage />);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('scroll-container')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const scrollContainer = screen.getByTestId('scroll-container');
|
||||
|
||||
// Simulate scroll that is NOT at the bottom
|
||||
await act(async () => {
|
||||
fireEvent.click(scrollContainer);
|
||||
});
|
||||
|
||||
// Verify that the API was not called since we're not at the bottom
|
||||
expect(getIngestionPipelineLogById).toHaveBeenCalledWith(
|
||||
'c379d75a-43cd-4d93-a799-0bba4a22c690',
|
||||
'1'
|
||||
);
|
||||
});
|
||||
|
||||
it('should not call handleScroll when user scrolls and is at the bottom with 40 margin', async () => {
|
||||
mockScrollPosition = { scrollTop: 40, scrollHeight: 100, clientHeight: 20 };
|
||||
|
||||
await act(async () => {
|
||||
render(<LogsViewerPage />);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('scroll-container')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const scrollContainer = screen.getByTestId('scroll-container');
|
||||
|
||||
// Simulate scroll that is NOT at the bottom
|
||||
await act(async () => {
|
||||
fireEvent.click(scrollContainer);
|
||||
});
|
||||
|
||||
// Verify that the API was not called since we're not at the bottom
|
||||
expect(getIngestionPipelineLogById).not.toHaveBeenCalledWith(
|
||||
'c379d75a-43cd-4d93-a799-0bba4a22c690',
|
||||
'1'
|
||||
);
|
||||
});
|
||||
|
||||
it('should not call handleScroll when user scrolls and is at the bottom but after is undefined', async () => {
|
||||
mockScrollPosition = { scrollTop: 80, scrollHeight: 100, clientHeight: 20 };
|
||||
(getIngestionPipelineLogById as jest.Mock).mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
data: {
|
||||
...mockLogsData,
|
||||
after: undefined,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
render(<LogsViewerPage />);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('scroll-container')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const scrollContainer = screen.getByTestId('scroll-container');
|
||||
|
||||
// Simulate scroll that is NOT at the bottom
|
||||
await act(async () => {
|
||||
fireEvent.click(scrollContainer);
|
||||
});
|
||||
|
||||
// Verify that the API was not called since we're not at the bottom
|
||||
expect(getIngestionPipelineLogById).not.toHaveBeenCalledWith(
|
||||
'c379d75a-43cd-4d93-a799-0bba4a22c690',
|
||||
'1'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -217,13 +217,17 @@ const LogsViewerPage = () => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleScroll = (event: Event) => {
|
||||
const targetElement = event.target as HTMLDivElement;
|
||||
|
||||
const scrollTop = targetElement.scrollTop;
|
||||
const scrollHeight = targetElement.scrollHeight;
|
||||
const clientHeight = targetElement.clientHeight;
|
||||
const isBottom = clientHeight + scrollTop === scrollHeight;
|
||||
const handleScroll = (scrollValues: {
|
||||
scrollTop: number;
|
||||
scrollHeight: number;
|
||||
clientHeight: number;
|
||||
}) => {
|
||||
const scrollTop = scrollValues.scrollTop;
|
||||
const scrollHeight = scrollValues.scrollHeight;
|
||||
const clientHeight = scrollValues.clientHeight;
|
||||
// Fetch more logs when user is at the bottom of the log
|
||||
// with a margin of about 40px (approximate height of one line)
|
||||
const isBottom = Math.abs(clientHeight + scrollTop - scrollHeight) < 40;
|
||||
|
||||
if (
|
||||
!isLogsLoading &&
|
||||
@ -238,20 +242,6 @@ const LogsViewerPage = () => {
|
||||
return;
|
||||
};
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const logBody = document.getElementsByClassName(
|
||||
'ReactVirtualized__Grid'
|
||||
)[0];
|
||||
|
||||
if (logBody) {
|
||||
logBody.addEventListener('scroll', handleScroll, { passive: true });
|
||||
}
|
||||
|
||||
return () => {
|
||||
logBody && logBody.removeEventListener('scroll', handleScroll);
|
||||
};
|
||||
});
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const lazyLogSearchBarInput = document.getElementsByClassName(
|
||||
'react-lazylog-searchbar-input'
|
||||
@ -420,6 +410,7 @@ const LogsViewerPage = () => {
|
||||
extraLines={1} // 1 is to be add so that linux users can see last line of the log
|
||||
ref={lazyLogRef}
|
||||
text={logs}
|
||||
onScroll={handleScroll}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user