diff --git a/src/components/LogList/LogActionBar.tsx b/src/components/LogList/LogActionBar.tsx index 188b43ab..17e038f4 100644 --- a/src/components/LogList/LogActionBar.tsx +++ b/src/components/LogList/LogActionBar.tsx @@ -2,12 +2,11 @@ import React from 'react'; import styled from 'styled-components'; import { useTranslation } from 'react-i18next'; import Button from '../Button'; -import { NotificationType, useNotifications, Notification } from '../Notifications'; +import { NotificationType, useNotifications } from '../Notifications'; import copy from 'copy-to-clipboard'; import Icon from '../Icon'; import { LocalSearchType, LogItem } from '../../hooks/useLogData'; import FilterInput from '../FilterInput'; -import { TFunction } from 'i18next'; // // Typedef @@ -21,28 +20,6 @@ type LogActionBarProps = { spaceAround?: boolean; }; -const handleFilterChange = (search: LocalSearchType) => (key: string) => { - search.search(key); -}; - -const handleFilterSubmit = (search: LocalSearchType) => () => { - search.nextResult(); -}; - -const handleCopyButtonClick = - ( - addNotification: (...notification: Notification[]) => void, - data: LogItem[], - t: TFunction<'translation', undefined, 'translation'>, - ) => - () => { - copy(data.map((item) => (typeof item === 'object' ? item.line : item)).join('\n')); - addNotification({ - type: NotificationType.Info, - message: t('task.all-logs-copied'), - }); - }; - // // Component // @@ -57,14 +34,19 @@ const LogActionBar: React.FC = ({ const { addNotification } = useNotifications(); const { t } = useTranslation(); + console.log('LogActionBar render'); return ( <> { + search.search(e); + }} + onSubmit={() => { + search.nextResult(); + }} noClear customIcon={['search', 'sm']} customIconElement={ @@ -84,7 +66,13 @@ const LogActionBar: React.FC = ({ data-testid="log-action-button" title={t('task.copy-logs-to-clipboard') ?? ''} iconOnly - onClick={handleCopyButtonClick(addNotification, data, t)} + onClick={() => { + copy(data.map((item) => (typeof item === 'object' ? item.line : item)).join('\n')); + addNotification({ + type: NotificationType.Info, + message: t('task.all-logs-copied'), + }); + }} > diff --git a/src/components/LogList/__tests__/LogActionBar.test.cypress.tsx b/src/components/LogList/__tests__/LogActionBar.test.cypress.tsx index 51db2c1d..51181787 100644 --- a/src/components/LogList/__tests__/LogActionBar.test.cypress.tsx +++ b/src/components/LogList/__tests__/LogActionBar.test.cypress.tsx @@ -15,14 +15,14 @@ const Search = { }; describe('LogActionBar', () => { - it('Should render only download and fullscreen buttons since there is no log data', () => { + it('Should render empty action bar since there is no log data', () => { mount( , ); - gid('log-action-bar').children().should('have.length', 2); + gid('log-action-bar').children().should('have.length', 0); }); it('Should render action bar with two buttons', () => { diff --git a/src/components/LogList/__tests__/LogList.test.cypress.tsx b/src/components/LogList/__tests__/LogList.test.cypress.tsx index 80e1dcd0..1884633b 100644 --- a/src/components/LogList/__tests__/LogList.test.cypress.tsx +++ b/src/components/LogList/__tests__/LogList.test.cypress.tsx @@ -32,7 +32,15 @@ function generateLines(amount: number) { const LIST_CONTAINER_CLASS = 'ReactVirtualized__List'; describe('LogActionBar', () => { + it('Should render empty wrapper in initial situation', () => { + mount( + + + , + ); + gid('loglist-wrapper').children().should('have.length', 1); + }); it('Should render message about empty preload when preload was empty or error and final fetch is not started', () => { mount( diff --git a/src/components/LogList/index.tsx b/src/components/LogList/index.tsx index 6e078448..b735088f 100644 --- a/src/components/LogList/index.tsx +++ b/src/components/LogList/index.tsx @@ -109,14 +109,6 @@ const LogList: React.FC = ({ logdata, fixedHeight, onScroll }) => { [onScroll], ); - const handleScroll = (args: { scrollTop: number; clientHeight: number; scrollHeight: number }) => { - if (args.scrollTop + args.clientHeight >= args.scrollHeight) { - setStickBottom(true); - } else if (stickBottom) { - setStickBottom(false); - } - }; - return (
{rows.length === 0 && ['Ok', 'Error'].includes(logdata.preloadStatus) && logdata.status === 'NotAsked' && ( @@ -136,7 +128,13 @@ const LogList: React.FC = ({ logdata, fixedHeight, onScroll }) => { rowHeight={cache.rowHeight} onRowsRendered={onRowsRendered} deferredMeasurementCache={cache} - onScroll={handleScroll} + onScroll={(args: { scrollTop: number; clientHeight: number; scrollHeight: number }) => { + if (args.scrollTop + args.clientHeight >= args.scrollHeight) { + setStickBottom(true); + } else if (stickBottom) { + setStickBottom(false); + } + }} rowRenderer={({ index, style, diff --git a/src/hooks/useLogData/index.ts b/src/hooks/useLogData/index.ts index 4d0becea..749be37d 100644 --- a/src/hooks/useLogData/index.ts +++ b/src/hooks/useLogData/index.ts @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { Log, AsyncStatus, APIError } from '../../types'; import { DataModel, defaultError } from '../../hooks/useResource'; import { apiHttp } from '../../constants'; @@ -78,7 +78,7 @@ const useLogData = ({ preload, paused, url, pagesize }: LogDataSettings): LogDat .then((response) => response.json()) .then((result: DataModel | APIError) => { if (isOkResult(result)) { - // Check if there was any new lines. If there wasn't, let's cancel post finish polling. + // Check if there was any new lines. If there wasnt, lets cancel post finish polling. // Or if was postpoll and we didnt get any results if ( (result.data.length > 0 && logs.length > 0 && result.data[0].row === logs.length - 1) || @@ -213,34 +213,31 @@ const useLogData = ({ preload, paused, url, pagesize }: LogDataSettings): LogDat const [searchResult, setSearchResult] = useState(emptySearchResult); - const search = useCallback( - (str: string) => { - if (!str) { - return setSearchResult(emptySearchResult); - } - const query = str.toLowerCase(); - const results = logs - .filter(filterbySearchTerm) - .filter((line) => line.line.toLowerCase().indexOf(query) > -1) - .map((item) => { - const index = item.line.toLowerCase().indexOf(query); - return { - line: item.row, - char: [index, index + str.length] as [number, number], - }; - }); - setSearchResult({ active: true, result: results, current: 0, query: str }); - }, - [logs], - ); + function search(str: string) { + if (!str) { + return setSearchResult(emptySearchResult); + } + const query = str.toLowerCase(); + const results = logs + .filter(filterbySearchTerm) + .filter((line) => line.line.toLowerCase().indexOf(query) > -1) + .map((item) => { + const index = item.line.toLowerCase().indexOf(query); + return { + line: item.row, + char: [index, index + str.length] as [number, number], + }; + }); + setSearchResult({ active: true, result: results, current: 0, query: str }); + } - const nextResult = useCallback(() => { + function nextResult() { if (searchResult.current === searchResult.result.length - 1) { setSearchResult((cur) => ({ ...cur, current: 0 })); } else { setSearchResult((cur) => ({ ...cur, current: cur.current + 1 })); } - }, [searchResult]); + } // Clean up on url change useEffect(() => { @@ -254,9 +251,7 @@ const useLogData = ({ preload, paused, url, pagesize }: LogDataSettings): LogDat }; }, [url]); - const localSearch = useMemo(() => ({ search, nextResult, result: searchResult }), [nextResult, search, searchResult]); - - return { logs, status, preloadStatus, error, loadMore, localSearch }; + return { logs, status, preloadStatus, error, loadMore, localSearch: { search, nextResult, result: searchResult } }; }; function filterbySearchTerm(item: LogItem): item is Log {