Fix/olm disable scrolling when no activity data 116594 (#118406) (#118528)

* commit using ashokaditya@elastic.co

* Disable scroll to fetch trigger when no data

fixes elastic/kibana/issues/116594

Co-Authored-By: Ashokaditya <1849116+ashokaditya@users.noreply.github.com>

* add a test for the fix

fixes elastic/kibana/issues/116594

Co-Authored-By: Ashokaditya <1849116+ashokaditya@users.noreply.github.com>

* use userEvent instead

Co-Authored-By: Ashokaditya <1849116+ashokaditya@users.noreply.github.com>

* use getEndpointDetailsPath instead of hardcoded paths

review suggestion

* scroll to bottom before looking for trigger element

* use WaitFor

review changes

* simplify

review changes

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Ashokaditya <1849116+ashokaditya@users.noreply.github.com>
This commit is contained in:
Kibana Machine 2021-11-15 10:53:24 -05:00 committed by GitHub
parent 8e35ee06b0
commit 14076aae70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 75 additions and 23 deletions

View file

@ -71,6 +71,11 @@ export const EndpointActivityLog = memo(
[hasActiveDateRange, isPagingDisabled, activityLogLoading, activityLogSize]
);
const showCallout = useMemo(
() => !isPagingDisabled && activityLogLoaded && !activityLogData.length,
[isPagingDisabled, activityLogLoaded, activityLogData]
);
const loadMoreTrigger = useRef<HTMLInputElement | null>(null);
const getActivityLog = useCallback(
(entries: IntersectionObserverEntry[]) => {
@ -120,7 +125,7 @@ export const EndpointActivityLog = memo(
<>
<DateRangePicker />
<EuiFlexItem grow={true}>
{!isPagingDisabled && activityLogLoaded && !activityLogData.length && (
{showCallout && (
<>
<EuiSpacer size="m" />
<EuiCallOut
@ -142,8 +147,11 @@ export const EndpointActivityLog = memo(
</EuiFlexItem>
<EuiFlexItem grow={false}>
{activityLogLoading && <EuiLoadingContent lines={3} />}
{(!activityLogLoading || !isPagingDisabled) && (
<LoadMoreTrigger ref={loadMoreTrigger} />
{(!activityLogLoading || !isPagingDisabled) && !showCallout && (
<LoadMoreTrigger
data-test-subj="activityLogLoadMoreTrigger"
ref={loadMoreTrigger}
/>
)}
{isPagingDisabled && !activityLogLoading && (
<EuiText color="subdued" textAlign="center">

View file

@ -7,6 +7,7 @@
import React from 'react';
import * as reactTestingLibrary from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { EndpointList } from './index';
import '../../../../common/mock/match_media';
@ -133,7 +134,7 @@ jest.mock('../../../../common/hooks/use_license');
describe('when on the endpoint list page', () => {
const docGenerator = new EndpointDocGenerator();
const { act, screen, fireEvent } = reactTestingLibrary;
const { act, screen, fireEvent, waitFor } = reactTestingLibrary;
let render: () => ReturnType<AppContextTestRender['render']>;
let history: AppContextTestRender['history'];
@ -885,16 +886,14 @@ describe('when on the endpoint list page', () => {
await middlewareSpy.waitForAction('serverReturnedEndpointList');
});
const hostNameLinks = renderResult.getAllByTestId('hostnameCellLink');
reactTestingLibrary.fireEvent.click(hostNameLinks[0]);
userEvent.click(hostNameLinks[0]);
});
afterEach(reactTestingLibrary.cleanup);
it('should show the endpoint details flyout', async () => {
const activityLogTab = await renderResult.findByTestId('activity_log');
reactTestingLibrary.act(() => {
reactTestingLibrary.fireEvent.click(activityLogTab);
});
userEvent.click(activityLogTab);
await middlewareSpy.waitForAction('endpointDetailsActivityLogChanged');
reactTestingLibrary.act(() => {
dispatchEndpointDetailsActivityLogChanged('success', getMockData());
@ -905,9 +904,7 @@ describe('when on the endpoint list page', () => {
it('should display log accurately', async () => {
const activityLogTab = await renderResult.findByTestId('activity_log');
reactTestingLibrary.act(() => {
reactTestingLibrary.fireEvent.click(activityLogTab);
});
userEvent.click(activityLogTab);
await middlewareSpy.waitForAction('endpointDetailsActivityLogChanged');
reactTestingLibrary.act(() => {
dispatchEndpointDetailsActivityLogChanged('success', getMockData());
@ -920,9 +917,7 @@ describe('when on the endpoint list page', () => {
it('should display log accurately with endpoint responses', async () => {
const activityLogTab = await renderResult.findByTestId('activity_log');
reactTestingLibrary.act(() => {
reactTestingLibrary.fireEvent.click(activityLogTab);
});
userEvent.click(activityLogTab);
await middlewareSpy.waitForAction('endpointDetailsActivityLogChanged');
reactTestingLibrary.act(() => {
dispatchEndpointDetailsActivityLogChanged(
@ -939,9 +934,7 @@ describe('when on the endpoint list page', () => {
it('should display empty state when API call has failed', async () => {
const activityLogTab = await renderResult.findByTestId('activity_log');
reactTestingLibrary.act(() => {
reactTestingLibrary.fireEvent.click(activityLogTab);
});
userEvent.click(activityLogTab);
await middlewareSpy.waitForAction('endpointDetailsActivityLogChanged');
reactTestingLibrary.act(() => {
dispatchEndpointDetailsActivityLogChanged('failed', getMockData());
@ -952,9 +945,7 @@ describe('when on the endpoint list page', () => {
it('should not display empty state when no log data', async () => {
const activityLogTab = await renderResult.findByTestId('activity_log');
reactTestingLibrary.act(() => {
reactTestingLibrary.fireEvent.click(activityLogTab);
});
userEvent.click(activityLogTab);
await middlewareSpy.waitForAction('endpointDetailsActivityLogChanged');
reactTestingLibrary.act(() => {
dispatchEndpointDetailsActivityLogChanged('success', {
@ -977,7 +968,12 @@ describe('when on the endpoint list page', () => {
const userChangedUrlChecker = middlewareSpy.waitForAction('userChangedUrl');
reactTestingLibrary.act(() => {
history.push(
`${MANAGEMENT_PATH}/endpoints?page_index=0&page_size=10&selected_endpoint=1&show=activity_log`
getEndpointDetailsPath({
page_index: '0',
page_size: '10',
name: 'endpointActivityLog',
selected_endpoint: '1',
})
);
});
const changedUrlAction = await userChangedUrlChecker;
@ -996,7 +992,12 @@ describe('when on the endpoint list page', () => {
const userChangedUrlChecker = middlewareSpy.waitForAction('userChangedUrl');
reactTestingLibrary.act(() => {
history.push(
`${MANAGEMENT_PATH}/endpoints?page_index=0&page_size=10&selected_endpoint=1&show=activity_log`
getEndpointDetailsPath({
page_index: '0',
page_size: '10',
name: 'endpointActivityLog',
selected_endpoint: '1',
})
);
});
const changedUrlAction = await userChangedUrlChecker;
@ -1018,11 +1019,54 @@ describe('when on the endpoint list page', () => {
expect(activityLogCallout).not.toBeNull();
});
it('should not display scroll trigger when showing callout message', async () => {
const userChangedUrlChecker = middlewareSpy.waitForAction('userChangedUrl');
reactTestingLibrary.act(() => {
history.push(
getEndpointDetailsPath({
page_index: '0',
page_size: '10',
name: 'endpointActivityLog',
selected_endpoint: '1',
})
);
});
const changedUrlAction = await userChangedUrlChecker;
expect(changedUrlAction.payload.search).toEqual(
'?page_index=0&page_size=10&selected_endpoint=1&show=activity_log'
);
await middlewareSpy.waitForAction('endpointDetailsActivityLogChanged');
reactTestingLibrary.act(() => {
dispatchEndpointDetailsActivityLogChanged('success', {
page: 1,
pageSize: 50,
startDate: 'now-1d',
endDate: 'now',
data: [],
});
});
const activityLogCallout = await renderResult.findByTestId('activityLogNoDataCallout');
expect(activityLogCallout).not.toBeNull();
// scroll to the bottom by pressing down arrow key
// and keep it pressed
userEvent.keyboard('ArrowDown>');
// end scrolling after 1s
await waitFor(() => {});
userEvent.keyboard('/ArrowDown');
expect(await renderResult.queryByTestId('activityLogLoadMoreTrigger')).toBeNull();
});
it('should correctly display non-empty comments only for actions', async () => {
const userChangedUrlChecker = middlewareSpy.waitForAction('userChangedUrl');
reactTestingLibrary.act(() => {
history.push(
`${MANAGEMENT_PATH}/endpoints?page_index=0&page_size=10&selected_endpoint=1&show=activity_log`
getEndpointDetailsPath({
page_index: '0',
page_size: '10',
name: 'endpointActivityLog',
selected_endpoint: '1',
})
);
});
const changedUrlAction = await userChangedUrlChecker;