mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Limit findings page size (#137187)
This commit is contained in:
parent
0be138c0a9
commit
11d4866155
12 changed files with 96 additions and 14 deletions
|
@ -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';
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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']>;
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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']>;
|
||||
|
|
|
@ -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';
|
|
@ -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,
|
|
@ -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);
|
||||
});
|
||||
});
|
|
@ -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 };
|
||||
};
|
|
@ -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) => {
|
Loading…
Add table
Add a link
Reference in a new issue