Limit findings page size (#137187)

This commit is contained in:
Jordan 2022-07-27 15:47:31 +03:00 committed by GitHub
parent 0be138c0a9
commit 11d4866155
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 96 additions and 14 deletions

View file

@ -19,7 +19,7 @@ import { encodeQuery } from '../../../common/navigation/query_utils';
import { useLocation } from 'react-router-dom';
import { RisonObject } from 'rison-node';
import { buildEsQuery } from '@kbn/es-query';
import { getPaginationQuery } from '../utils';
import { getPaginationQuery } from '../utils/utils';
import { FindingsEsPitContext } from '../es_pit/findings_es_pit_context';
import { chartPluginMock } from '@kbn/charts-plugin/public/mocks';
import { discoverPluginMock } from '@kbn/discover-plugin/public/mocks';

View file

@ -4,9 +4,9 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import React, { useMemo } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiSpacer } from '@elastic/eui';
import { EuiBottomBar, EuiSpacer, EuiText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import type { FindingsBaseProps } from '../types';
import { FindingsTable } from './latest_findings_table';
@ -23,11 +23,12 @@ import {
getPaginationTableParams,
useBaseEsQuery,
usePersistedQuery,
} from '../utils';
} from '../utils/utils';
import { PageTitle, PageTitleText } from '../layout/findings_layout';
import { FindingsGroupBySelector } from '../layout/findings_group_by_selector';
import { useUrlQuery } from '../../../common/hooks/use_url_query';
import { ErrorCallout } from '../layout/error_callout';
import { getLimitProperties } from '../utils/get_limit_properties';
export const getDefaultQuery = ({
query,
@ -40,6 +41,8 @@ export const getDefaultQuery = ({
pageSize: 10,
});
const MAX_ITEMS = 500;
export const LatestFindingsContainer = ({ dataView }: FindingsBaseProps) => {
const getPersistedDefaultQuery = usePersistedQuery(getDefaultQuery);
const { urlQuery, setUrlQuery } = useUrlQuery(getPersistedDefaultQuery);
@ -65,6 +68,17 @@ export const LatestFindingsContainer = ({ dataView }: FindingsBaseProps) => {
const error = findingsGroupByNone.error || baseEsQuery.error;
const { isLastLimitedPage, limitedTotalItemCount } = useMemo(
() =>
getLimitProperties(
findingsGroupByNone.data?.total || 0,
MAX_ITEMS,
urlQuery.pageSize,
urlQuery.pageIndex
),
[findingsGroupByNone.data?.total, urlQuery.pageIndex, urlQuery.pageSize]
);
return (
<div data-test-subj={TEST_SUBJECTS.FINDINGS_CONTAINER}>
<FindingsSearchBar
@ -103,7 +117,7 @@ export const LatestFindingsContainer = ({ dataView }: FindingsBaseProps) => {
pagination={getPaginationTableParams({
pageSize: urlQuery.pageSize,
pageIndex: urlQuery.pageIndex,
totalItemCount: findingsGroupByNone.data?.total || 0,
totalItemCount: limitedTotalItemCount,
})}
sorting={{
sort: { field: urlQuery.sort.field, direction: urlQuery.sort.direction },
@ -128,6 +142,22 @@ export const LatestFindingsContainer = ({ dataView }: FindingsBaseProps) => {
})
}
/>
{isLastLimitedPage && (
<>
<EuiSpacer size="xxl" />
<EuiBottomBar data-test-subj="test-bottom-bar">
<EuiText textAlign="center">
<FormattedMessage
id="xpack.csp.findings.latestFindings.bottomBarLabel"
defaultMessage="These are the first {maxItems} findings matching your search, refine your search to see others."
values={{
maxItems: MAX_ITEMS,
}}
/>
</EuiText>
</EuiBottomBar>
</>
)}
</>
)}
</div>

View file

@ -19,7 +19,7 @@ import type { CspFinding, Sort } from '../types';
import { useKibana } from '../../../common/hooks/use_kibana';
import type { FindingsBaseEsQuery } from '../types';
import { FINDINGS_REFETCH_INTERVAL_MS } from '../constants';
import { getAggregationCount, getFindingsCountAggQuery } from '../utils';
import { getAggregationCount, getFindingsCountAggQuery } from '../utils/utils';
interface UseFindingsOptions extends FindingsBaseEsQuery {
from: NonNullable<estypes.SearchRequest['from']>;

View file

@ -22,7 +22,7 @@ import {
getPaginationTableParams,
useBaseEsQuery,
usePersistedQuery,
} from '../utils';
} from '../utils/utils';
import { PageTitle, PageTitleText } from '../layout/findings_layout';
import { FindingsGroupBySelector } from '../layout/findings_group_by_selector';
import { findingsNavigation } from '../../../common/navigation/constants';

View file

@ -24,7 +24,7 @@ import {
getPaginationTableParams,
useBaseEsQuery,
usePersistedQuery,
} from '../../utils';
} from '../../utils/utils';
import { ResourceFindingsTable } from './resource_findings_table';
import { FindingsSearchBar } from '../../layout/findings_search_bar';
import { ErrorCallout } from '../../layout/error_callout';

View file

@ -11,12 +11,12 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { Pagination } from '@elastic/eui';
import { useContext } from 'react';
import { number } from 'io-ts';
import { getAggregationCount, getFindingsCountAggQuery } from '../../utils/utils';
import { FindingsEsPitContext } from '../../es_pit/findings_es_pit_context';
import { FINDINGS_REFETCH_INTERVAL_MS } from '../../constants';
import { useKibana } from '../../../../common/hooks/use_kibana';
import { showErrorToast } from '../../latest_findings/use_latest_findings';
import type { CspFinding, FindingsBaseEsQuery, Sort } from '../../types';
import { getAggregationCount, getFindingsCountAggQuery } from '../../utils';
interface UseResourceFindingsOptions extends FindingsBaseEsQuery {
resourceId: string;

View file

@ -15,7 +15,7 @@ import { FINDINGS_REFETCH_INTERVAL_MS } from '../constants';
import { useKibana } from '../../../common/hooks/use_kibana';
import { showErrorToast } from '../latest_findings/use_latest_findings';
import type { FindingsBaseEsQuery, Sort } from '../types';
import { getAggregationCount, getFindingsCountAggQuery } from '../utils';
import { getAggregationCount, getFindingsCountAggQuery } from '../utils/utils';
interface UseFindingsByResourceOptions extends FindingsBaseEsQuery {
from: NonNullable<estypes.SearchRequest['from']>;

View file

@ -4,7 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { CSP_LATEST_FINDINGS_DATA_VIEW } from '../../../common/constants';
import { CSP_LATEST_FINDINGS_DATA_VIEW } from '../../../../common/constants';
import { createStubDataView } from '@kbn/data-views-plugin/common/stubs';
import { DataView } from '@kbn/data-views-plugin/common';
import { getFilters } from './get_filters';

View file

@ -14,7 +14,7 @@ import {
FilterCompareOptions,
} from '@kbn/es-query';
import type { Serializable } from '@kbn/utility-types';
import type { FindingsBaseProps } from './types';
import type { FindingsBaseProps } from '../types';
const compareOptions: FilterCompareOptions = {
negate: false,

View file

@ -0,0 +1,31 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { getLimitProperties } from './get_limit_properties';
describe('getLimitProperties', () => {
it('less items than limit', () => {
const { limitedTotalItemCount, isLastLimitedPage } = getLimitProperties(200, 500, 100, 1);
expect(limitedTotalItemCount).toBe(200);
expect(isLastLimitedPage).toBe(false);
});
it('more items than limit', () => {
const { limitedTotalItemCount, isLastLimitedPage } = getLimitProperties(600, 500, 100, 4);
expect(limitedTotalItemCount).toBe(500);
expect(isLastLimitedPage).toBe(true);
});
it('per page calculations are correct', () => {
const { limitedTotalItemCount, isLastLimitedPage } = getLimitProperties(600, 500, 25, 19);
expect(limitedTotalItemCount).toBe(500);
expect(isLastLimitedPage).toBe(true);
});
});

View file

@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export const getLimitProperties = (
totalItems: number,
maxItems: number,
pageSize: number,
pageIndex: number
): { isLastLimitedPage: boolean; limitedTotalItemCount: number } => {
const limitItems = totalItems > maxItems;
const limitedTotalItemCount = limitItems ? maxItems : totalItems;
const lastLimitedPage = Math.ceil(limitedTotalItemCount / pageSize);
const isLastPage = lastLimitedPage === pageIndex + 1;
const isLastLimitedPage = limitItems && isLastPage;
return { isLastLimitedPage, limitedTotalItemCount };
};

View file

@ -10,8 +10,8 @@ import { EuiBasicTableProps, Pagination } from '@elastic/eui';
import { useCallback, useEffect, useMemo } from 'react';
import { i18n } from '@kbn/i18n';
import type { estypes } from '@elastic/elasticsearch';
import type { FindingsBaseProps, FindingsBaseURLQuery } from './types';
import { useKibana } from '../../common/hooks/use_kibana';
import type { FindingsBaseProps, FindingsBaseURLQuery } from '../types';
import { useKibana } from '../../../common/hooks/use_kibana';
export { getFilters } from './get_filters';
const getBaseQuery = ({ dataView, query, filters }: FindingsBaseURLQuery & FindingsBaseProps) => {