diff --git a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.test.tsx b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.test.tsx index 26ebb7ff5d359..fbd43787a822e 100644 --- a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.test.tsx +++ b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.test.tsx @@ -10,8 +10,8 @@ import * as api from '../api'; import { createKibanaCoreStartMock } from '../../common/mocks/kibana_core'; import { getExceptionListSchemaMock } from '../../../common/schemas/response/exception_list_schema.mock'; import { getExceptionListItemSchemaMock } from '../../../common/schemas/response/exception_list_item_schema.mock'; -import { ExceptionListSchema } from '../../../common/schemas'; -import { ExceptionItemsAndPagination, UseExceptionListProps } from '../types'; +import { ExceptionListItemSchema } from '../../../common/schemas'; +import { ExceptionList, UseExceptionListProps } from '../types'; import { ReturnExceptionListAndItems, useExceptionList } from './use_exception_list'; @@ -35,14 +35,23 @@ describe('useExceptionList', () => { >(() => useExceptionList({ http: mockKibanaHttpService, - id: 'myListId', - namespaceType: 'single', + lists: [{ id: 'myListId', namespaceType: 'single' }], onError: onErrorMock, }) ); await waitForNextUpdate(); - expect(result.current).toEqual([true, null, null, null]); + expect(result.current).toEqual([ + true, + [], + [], + { + page: 1, + perPage: 20, + total: 0, + }, + null, + ]); }); }); @@ -54,30 +63,31 @@ describe('useExceptionList', () => { >(() => useExceptionList({ http: mockKibanaHttpService, - id: 'myListId', - namespaceType: 'single', + lists: [{ id: 'myListId', namespaceType: 'single' }], onError: onErrorMock, }) ); await waitForNextUpdate(); await waitForNextUpdate(); - const expectedListResult: ExceptionListSchema = getExceptionListSchemaMock(); + const expectedListResult: ExceptionList[] = [ + { ...getExceptionListSchemaMock(), totalItems: 1 }, + ]; - const expectedListItemsResult: ExceptionItemsAndPagination = { - items: [getExceptionListItemSchemaMock()], - pagination: { - page: 1, - perPage: 20, - total: 1, - }, - }; + const expectedListItemsResult: ExceptionListItemSchema[] = [ + { ...getExceptionListItemSchemaMock() }, + ]; expect(result.current).toEqual([ false, expectedListResult, expectedListItemsResult, - result.current[3], + { + page: 1, + perPage: 20, + total: 1, + }, + result.current[4], ]); }); }); @@ -90,13 +100,12 @@ describe('useExceptionList', () => { UseExceptionListProps, ReturnExceptionListAndItems >( - ({ filterOptions, http, id, namespaceType, pagination, onError }) => - useExceptionList({ filterOptions, http, id, namespaceType, onError, pagination }), + ({ filterOptions, http, lists, pagination, onError }) => + useExceptionList({ filterOptions, http, lists, onError, pagination }), { initialProps: { http: mockKibanaHttpService, - id: 'myListId', - namespaceType: 'single', + lists: [{ id: 'myListId', namespaceType: 'single' }], onError: onErrorMock, }, } @@ -104,8 +113,7 @@ describe('useExceptionList', () => { await waitForNextUpdate(); rerender({ http: mockKibanaHttpService, - id: 'newListId', - namespaceType: 'single', + lists: [{ id: 'newListId', namespaceType: 'single' }], onError: onErrorMock, }); await waitForNextUpdate(); @@ -125,18 +133,17 @@ describe('useExceptionList', () => { >(() => useExceptionList({ http: mockKibanaHttpService, - id: 'myListId', - namespaceType: 'single', + lists: [{ id: 'myListId', namespaceType: 'single' }], onError: onErrorMock, }) ); await waitForNextUpdate(); await waitForNextUpdate(); - expect(typeof result.current[3]).toEqual('function'); + expect(typeof result.current[4]).toEqual('function'); - if (result.current[3] != null) { - result.current[3]({ listId: 'myListId', listNamespaceType: 'single' }); + if (result.current[4] != null) { + result.current[4](); } await waitForNextUpdate(); @@ -157,8 +164,7 @@ describe('useExceptionList', () => { () => useExceptionList({ http: mockKibanaHttpService, - id: 'myListId', - namespaceType: 'single', + lists: [{ id: 'myListId', namespaceType: 'single' }], onError: onErrorMock, }) ); @@ -180,8 +186,7 @@ describe('useExceptionList', () => { () => useExceptionList({ http: mockKibanaHttpService, - id: 'myListId', - namespaceType: 'single', + lists: [{ id: 'myListId', namespaceType: 'single' }], onError: onErrorMock, }) ); diff --git a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.tsx b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.tsx index c26d556fe8f25..1d7a63ba880bf 100644 --- a/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.tsx +++ b/x-pack/plugins/lists/public/exceptions/hooks/use_exception_list.tsx @@ -8,7 +8,7 @@ import { useEffect, useMemo, useRef, useState } from 'react'; import { fetchExceptionListById, fetchExceptionListItemsByListId } from '../api'; import { ExceptionIdentifiers, ExceptionList, Pagination, UseExceptionListProps } from '../types'; -import { ExceptionListItemSchema, ExceptionListSchema } from '../../../common/schemas'; +import { ExceptionListItemSchema } from '../../../common/schemas'; type Func = () => void; export type ReturnExceptionListAndItems = [ @@ -45,9 +45,7 @@ export const useExceptionList = ({ onError, dispatchListsInReducer, }: UseExceptionListProps): ReturnExceptionListAndItems => { - const [exceptionLists, setExceptionLists] = useState< - Array - >([]); + const [exceptionLists, setExceptionLists] = useState([]); const [exceptionItems, setExceptionListItems] = useState([]); const [paginationInfo, setPagination] = useState(pagination); const fetchExceptionList = useRef(null); @@ -142,10 +140,6 @@ export const useExceptionList = ({ onError(error); } } - - if (isSubscribed) { - setLoading(false); - } }; // TODO: Workaround for now. Once api updated, we can pass in array of lists to fetch @@ -155,6 +149,10 @@ export const useExceptionList = ({ fetchData({ id, namespaceType }) ) ); + + if (isSubscribed) { + setLoading(false); + } }; fetchLists(); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_pagination.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_pagination.tsx index 48d15dd6ae333..fdbee42c4eea8 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_pagination.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/exceptions_pagination.tsx @@ -71,7 +71,11 @@ const ExceptionsViewerPaginationComponent = ({ }, [pagination, onPaginationChange]); const totalPages = useMemo((): number => { - return Math.ceil(pagination.totalItemCount / pagination.pageSize); + if (pagination.totalItemCount > 0) { + return Math.ceil(pagination.totalItemCount / pagination.pageSize); + } else { + return 1; + } }, [pagination]); return ( diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx index 31cff134d2dc4..946a98b19decd 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/viewer/index.tsx @@ -311,8 +311,8 @@ const ExceptionsViewerComponent = ({ }, [filterOptions.showEndpointList, filterOptions.showDetectionsList, ruleSettingsUrl]); const showEmpty = useMemo((): boolean => { - return !initLoading && exceptions.length === 0; - }, [initLoading, exceptions.length]); + return !initLoading && !loadingList && exceptions.length === 0; + }, [initLoading, exceptions.length, loadingList]); return ( <>