feat: added goto top feature in list logs veiw (#3146)

This commit is contained in:
Palash Gupta 2023-07-17 13:42:05 +05:30 committed by GitHub
parent 7f9ba6c43a
commit 22d0aa951c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 134 additions and 9 deletions

View File

@ -0,0 +1,29 @@
import { ArrowUpOutlined } from '@ant-design/icons';
import { FloatButton } from 'antd';
import { PANEL_TYPES } from 'constants/queryBuilder';
// hooks
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import useScrollToTop from 'hooks/useScrollToTop';
function GoToTop(): JSX.Element | null {
const { isVisible, scrollToTop } = useScrollToTop();
const { panelType } = useQueryBuilder();
if (!isVisible) return null;
if (panelType === PANEL_TYPES.LIST) {
return (
<FloatButton
onClick={scrollToTop}
shape="circle"
type="primary"
icon={<ArrowUpOutlined />}
/>
);
}
return null;
}
export default GoToTop;

View File

@ -1,5 +1,4 @@
import { TabsProps } from 'antd';
import axios from 'axios';
import LogDetail from 'components/LogDetail';
import TabLabel from 'components/TabLabel';
import { QueryParams } from 'constants/query';
@ -13,6 +12,7 @@ import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
import ROUTES from 'constants/routes';
import { DEFAULT_PER_PAGE_VALUE } from 'container/Controls/config';
import ExportPanel from 'container/ExportPanel';
import GoToTop from 'container/GoToTop';
import LogsExplorerChart from 'container/LogsExplorerChart';
import LogsExplorerList from 'container/LogsExplorerList';
import LogsExplorerTable from 'container/LogsExplorerTable';
@ -22,6 +22,7 @@ import { useUpdateDashboard } from 'hooks/dashboard/useUpdateDashboard';
import { addEmptyWidgetInDashboardJSONWithQuery } from 'hooks/dashboard/utils';
import { useGetExplorerQueryRange } from 'hooks/queryBuilder/useGetExplorerQueryRange';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import useAxiosError from 'hooks/useAxiosError';
import { useNotifications } from 'hooks/useNotifications';
import useUrlQueryData from 'hooks/useUrlQueryData';
import { chooseAutocompleteFromCustomValue } from 'lib/newQueryBuilder/chooseAutocompleteFromCustomValue';
@ -81,6 +82,8 @@ function LogsExplorerViews(): JSX.Element {
const [logs, setLogs] = useState<ILog[]>([]);
const [requestData, setRequestData] = useState<Query | null>(null);
const handleAxisError = useAxiosError();
const currentStagedQueryData = useMemo(() => {
if (!stagedQuery || stagedQuery.builder.queryData.length !== 1) return null;
@ -357,16 +360,16 @@ function LogsExplorerViews(): JSX.Element {
history.push(dashboardEditView);
},
onError: (error) => {
if (axios.isAxiosError(error)) {
notifications.error({
message: error.message,
});
}
},
onError: handleAxisError,
});
},
[exportDefaultQuery, history, notifications, updateDashboard],
[
exportDefaultQuery,
history,
notifications,
updateDashboard,
handleAxisError,
],
);
useEffect(() => {
@ -511,6 +514,8 @@ function LogsExplorerViews(): JSX.Element {
onAddToQuery={handleAddToQuery}
onClickActionItem={handleAddToQuery}
/>
<GoToTop />
</>
);
}

View File

@ -0,0 +1,29 @@
import throttle from 'lodash-es/throttle';
import { useEffect, useState } from 'react';
import { UseScrollToTop } from './types';
function useScrollToTop(visibleOffset = 200): UseScrollToTop {
const [isVisible, setIsVisible] = useState<boolean>(false);
const scrollToTop = (): void => {
window.scrollTo({
top: 0,
behavior: 'smooth',
});
};
useEffect(() => {
const toggleVisibility = throttle(() => {
setIsVisible(window.pageYOffset > visibleOffset);
}, 300);
window.addEventListener('scroll', toggleVisibility);
return (): void => window.removeEventListener('scroll', toggleVisibility);
}, [visibleOffset]);
return { isVisible, scrollToTop };
}
export default useScrollToTop;

View File

@ -0,0 +1,4 @@
export interface UseScrollToTop {
isVisible: boolean;
scrollToTop: VoidFunction;
}

View File

@ -0,0 +1,58 @@
import { act, renderHook } from '@testing-library/react';
import useScrollToTop from './index';
// Mocking window.scrollTo method
global.scrollTo = jest.fn();
describe('useScrollToTop hook', () => {
beforeAll(() => {
jest.useFakeTimers();
});
it('should change visibility and scroll to top on call', () => {
const { result } = renderHook(() => useScrollToTop(100));
// Simulate scrolling 150px down
act(() => {
global.pageYOffset = 150;
global.dispatchEvent(new Event('scroll'));
jest.advanceTimersByTime(300);
});
expect(result.current.isVisible).toBe(true);
// Simulate scrolling to top
act(() => {
result.current.scrollToTop();
});
expect(global.scrollTo).toHaveBeenCalledWith({ top: 0, behavior: 'smooth' });
});
it('should be invisible when scrolled less than offset', () => {
const { result } = renderHook(() => useScrollToTop(100));
// Simulate scrolling 50px down
act(() => {
global.pageYOffset = 50;
global.dispatchEvent(new Event('scroll'));
jest.advanceTimersByTime(300);
});
expect(result.current.isVisible).toBe(false);
});
it('should be visible when scrolled more than offset', () => {
const { result } = renderHook(() => useScrollToTop(100));
// Simulate scrolling 50px down
act(() => {
global.pageYOffset = 200;
global.dispatchEvent(new Event('scroll'));
jest.advanceTimersByTime(300);
});
expect(result.current.isVisible).toBe(true);
});
});